Python對(duì)集合使用sort()排序報(bào)錯(cuò)AttributeError的解決方法
前言
你寫的代碼是這樣的:
cars = {'bmw', 'audi', 'toyota', 'soba'}
cars.sort()
print(cars)
運(yùn)行時(shí)會(huì)看到:
AttributeError: 'set' object has no attribute 'sort'
簡(jiǎn)單回答:set(集合)在 Python 是無序、不可索引的數(shù)據(jù)結(jié)構(gòu),它沒有 sort() 方法;sort() 是 list(列表)的方法。要對(duì)集合里的元素排序,需要先把集合轉(zhuǎn)成能排序的數(shù)據(jù)類型(比如 list 或 tuple),或者使用內(nèi)置函數(shù) sorted(),它會(huì)返回一個(gè)排好序的 列表。
下面詳細(xì)講原因、示例、常見誤區(qū)和實(shí)戰(zhàn)建議。
集合(set)和列表(list)的差別
set的特點(diǎn):無序、元素唯一。集合用于快速去重與成員測(cè)試(in 操作),內(nèi)部不保證元素的插入順序或任何順序行為。list的特點(diǎn):有序、可重復(fù)、可索引,可以使用list.sort()就地排序(改變?cè)斜恚蛘哂?sorted()返回一個(gè)新列表。
因?yàn)?set 沒有“位置索引”的概念(不像 list 有索引 0、1、2),所以沒有內(nèi)置就地排序方法 sort()。這就是你看到 AttributeError 的根本原因。
如何正確地對(duì)集合內(nèi)容排序
方法 A:使用sorted()(最常用、簡(jiǎn)潔、安全)
sorted() 接受任意可迭代對(duì)象,返回一個(gè) 已排序的列表(不改變?cè)希?/p>
示例:
cars = {'bmw', 'audi', 'toyota', 'soba'}
sorted_cars = sorted(cars) # 返回列表,默認(rèn)按字母序升序
print(sorted_cars) # ['audi', 'bmw', 'soba', 'toyota']
說明:
sorted()不會(huì)改變cars,它返回一個(gè)新的list。sorted()支持key和reverse參數(shù),比如sorted(cars, key=str.lower, reverse=True)。
把集合轉(zhuǎn)為列表然后用 list.sort()
如果你想復(fù)用同一個(gè)容器并就地修改順序,可以先 list() 轉(zhuǎn)換:
cars = {'bmw', 'audi', 'toyota', 'soba'}
cars_list = list(cars)
cars_list.sort() # 就地排序,返回 None
print(cars_list) # ['audi', 'bmw', 'soba', 'toyota']
注意:list.sort() 會(huì)改變 cars_list,且返回 None(這點(diǎn)常讓人困惑)。
需要“有序集合”語義
如果你既想去重又需要維持排序/順序,通常有兩種做法:
使用 sorted(set) 得到排序后的列表(去重 + 排序)。
從 Python 3.7 起,dict 保持插入順序,可以用 dict.fromkeys(...) 保留原順序去重:
items = ['a', 'b', 'a', 'c'] unique_preserve_order = list(dict.fromkeys(items))
若需要一個(gè)真正的“有序集合”數(shù)據(jù)結(jié)構(gòu),可以用第三方庫比如 sortedcontainers(SortedSet)或 collections.OrderedDict 組合,但在大多數(shù)場(chǎng)景下 sorted() 或 list 就夠了。
可運(yùn)行的多場(chǎng)景 Demo
下面給出多個(gè)實(shí)用 demo,包括排序、按長(zhǎng)度排序、忽略大小寫排序、處理混合類型的注意事項(xiàng)等。把下面的代碼保存為 cars_demo.py,運(yùn)行 python cars_demo.py 觀察輸出。
# cars_demo.py
# 演示:如何對(duì)集合排序,以及常見變體
def basic_sorted():
cars = {'bmw', 'audi', 'toyota', 'soba'}
print("原始集合(無序):", cars)
s = sorted(cars)
print("sorted() 返回列表(升序):", s)
def list_sort_inplace():
cars = {'bmw', 'audi', 'toyota', 'soba'}
cars_list = list(cars)
cars_list.sort() # 就地排序
print("list.sort() 就地排序后的列表:", cars_list)
def sorted_with_key_reverse():
cars = {'BMW', 'audi', 'Toyota', 'soba'}
# 忽略大小寫排序,并且結(jié)果反轉(zhuǎn)
result = sorted(cars, key=str.lower, reverse=True)
print("忽略大小寫并降序:", result)
def sort_by_length():
cars = {'bmw', 'audi', 'toyota', 'mini cooper', 'soba'}
# 按字符串長(zhǎng)度排序(短到長(zhǎng))
result = sorted(cars, key=len)
print("按字符串長(zhǎng)度排序:", result)
def mixing_types_issue():
# 當(dāng)集合里混合不可比較類型時(shí)會(huì)報(bào)錯(cuò)(比如 int 和 str 在 Python3 中不可直接比較)
try:
mixed = {1, '2', 3}
print(sorted(mixed)) # 這里會(huì)拋出 TypeError
except TypeError as e:
print("混合類型排序會(huì)報(bào)錯(cuò):", e)
if __name__ == "__main__":
basic_sorted()
list_sort_inplace()
sorted_with_key_reverse()
sort_by_length()
mixing_types_issue()
示例運(yùn)行后的典型輸出(注意集合打印順序可能不同):
原始集合(無序): {'toyota', 'audi', 'bmw', 'soba'}
sorted() 返回列表(升序): ['audi', 'bmw', 'soba', 'toyota']
list.sort() 就地排序后的列表: ['audi', 'bmw', 'soba', 'toyota']
忽略大小寫并降序: ['Toyota', 'soba', 'BMW', 'audi']
按字符串長(zhǎng)度排序: ['bmw', 'soba', 'audi', 'toyota', 'mini cooper']
混合類型排序會(huì)報(bào)錯(cuò): '<' not supported between instances of 'str' and 'int'
常見誤區(qū)與排錯(cuò)小貼士
誤以為 set 有順序:set 是無序的;即使打印時(shí)看到某種順序,也不能依賴它。
list.sort() 返回 None:list.sort() 是就地排序,不返回新列表;若想保留原列表,請(qǐng)用 sorted()。
sorted() vs list.sort():
sorted(iterable):任何可迭代對(duì)象,返回新列表(不改原對(duì)象)。list.sort():只適用于列表,就地排序(改變列表)。
類型不兼容會(huì)報(bào) TypeError:確保要排序的元素可以互相比較(或提供 key)。
如果需要去重且保持某種順序,不要直接用 set 保存已排序結(jié)果;可以先 sorted(set) 得到排序列表,或用 dict.fromkeys 保持插入去重。
實(shí)際場(chǎng)景建議
1.用 set 的場(chǎng)景:
- 你只關(guān)心成員是否存在(去重 / membership checks),不關(guān)心順序。
- 需要高性能去重或大量元素的去重操作。
2.用 list 的場(chǎng)景:
- 需要保留元素順序、索引訪問、切片或排序。
- 需要按位置展示元素(例如 UI 列表、寫入文件等)。
實(shí)際工程里常見模式:
從用戶輸入、數(shù)據(jù)庫或 API 獲取元素(可能含重復(fù)),先 set() 做去重,然后 sorted() 得到有序列表用于顯示或后續(xù)處理:
unique_sorted = sorted(set(items_from_user))
總結(jié)
set沒有sort()→ 因?yàn)榧鲜菬o序的。- 想排序集合,優(yōu)先用
sorted(set_obj)(返回列表)。 - 需要就地排序,先
list(set_obj)再list.sort()。 - 若集合元素類型混雜,排序會(huì)拋
TypeError;可用key或統(tǒng)一類型轉(zhuǎn)換。 - 若既要去重又要保持順序,考慮
sorted(set)或dict.fromkeys等技巧。
到此這篇關(guān)于 Python對(duì)集合使用sort()排序報(bào)錯(cuò)AttributeError的解決方法的文章就介紹到這了,更多相關(guān)Python集合排序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- python 對(duì)給定可迭代集合統(tǒng)計(jì)出現(xiàn)頻率,并排序的方法
- Python錯(cuò)誤AttributeError:?'NoneType' object?has?no?attribute問題的徹底解決方法
- Python2到Python3的遷移過程中報(bào)錯(cuò)AttributeError: ‘str‘ object has no attribute ‘decode‘問題的解決方案大全
- 解決python報(bào)錯(cuò):AttributeError:?'ImageDraw'?object?has?no?attribute?'textbbox'
- Python 中 AttributeError: ‘NoneType‘ object has no attribute ‘X‘ 錯(cuò)誤問題解決方案
- Python數(shù)據(jù)結(jié)構(gòu)集合的相關(guān)詳解
相關(guān)文章
python 多個(gè)參數(shù)不為空校驗(yàn)方法
今天小編就為大家分享一篇python 多個(gè)參數(shù)不為空校驗(yàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-02-02
django+tornado實(shí)現(xiàn)實(shí)時(shí)查看遠(yuǎn)程日志的方法
今天小編就為大家分享一篇django+tornado實(shí)現(xiàn)實(shí)時(shí)查看遠(yuǎn)程日志的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-08-08
使用pipenv管理python虛擬環(huán)境的全過程
pipenv 是Kenneth Reitz大神的作品,能夠有效管理Python多個(gè)環(huán)境,各種包,接下來通過本文給大家分享使用pipenv管理python虛擬環(huán)境的全過程,感興趣的朋友一起看看吧2021-09-09
教你一步步利用python實(shí)現(xiàn)貪吃蛇游戲
這篇文章主要給大家介紹了關(guān)于如何利用python實(shí)現(xiàn)貪吃蛇游戲的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
PyQt5實(shí)現(xiàn)數(shù)據(jù)的增刪改查功能詳解
這篇文章主要為大家介紹了如何使用Python中的PyQt5模塊來實(shí)現(xiàn)數(shù)據(jù)的增、刪、改、查功能,文中示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-03-03
python3.5 tkinter實(shí)現(xiàn)頁面跳轉(zhuǎn)
這篇文章主要為大家詳細(xì)介紹了python3.5 tkinter實(shí)現(xiàn)頁面跳轉(zhuǎn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
利用Python實(shí)現(xiàn)批量加密Excel文件
在日常工作中,我們經(jīng)常需要處理大量的Excel文件,為了保護(hù)敏感數(shù)據(jù)的安全性,我們可能需要對(duì)這些文件進(jìn)行加密,本文主要介紹了如何使用Python實(shí)現(xiàn)批量加密Excel文件,需要的可以參考下2023-11-11

