關於 Python 字典的 values() 方法返回值的順序?
dict_mark = {"Wang": "C", "Li": "B", "Ma": "A"}
s = ""
for c in dict_mark.values():
s += c
print(s)
關於這個字典列印出來一直是 CBA 的順序,可是字典不是應該無序嗎?stackoverflow的前輩們的答案我看的一知半解,能否請教知友們呢?
問題地址
另一答案地址
還有一個關於 dictionary 的(字典變有序了?)
無序的不代表隨機的,也不代表每次都是隨機的,這些詞有細微的差異。無序的只是說,你不該對順序有任何假定,既不能假定有確定順序,也不能假定沒有確定順序。
規範是指dict遍歷是不保證順序的,但一定保證每個元素都被遍歷一次
實現可以是無序,也可以是有序,都符合規範
Py3.5是無序的,3.6是有序的,但不能說dict就是有序的,因為如果3.7改成無序的也是正確的實現。
如果要使用有序dict,必須用OrderedDict
如果按照語言規範來看,Python的規範里沒有說明Dict是一個有序的類型。換句話說,dict就是無序的,因為語言規範不保證它按照什麼順序出來。要有序,請使用OrderedDict。
但是無序不是說每次輸出結果都不同,無序只是指結果不保證一定與插入順序一致而已。
CPython 3.6里對dict有個新的實現,使得字典內部存儲的順序不僅僅與key有關,還與插入順序有關。但是有關並不代表它就一定按照插入順序依次出現(似乎當字典實現在內存中進行擴展的時候就可能造成結果不一致),只不過表示如果key相同,插入順序相同,那麼結果也是相同的。
在此之前,用values和keys方法取到的list僅與key(準確的說是key的__hash__)有關而與插入順序無關。Python dictionary implementation
你看下 dict 的 CPython hash 實現就了解了
一般語言里的dict結構只是表面上說自己是無序的,實際上根據內部實現會有自己的一套順序,只是這個順序可能比較古怪,比較混沌,比較沒有統一標準,甚至可能以後實現變了順序也會變,所以設計者也不想告訴你究竟是個什麼順序,但是每次讀出來都會根據這個順序出。不過也有比較奇葩的語言每次讀出來的順序都不一樣,比如說golang。
沒有順序,包括.keys取鍵,.values取值,字典無序存儲不是逗你玩的,不管你在命令行里輸出多少次一樣的順序都不要上當!!!如果要取字典順序,請你老老實實用ordereddict!!這是我有一次在spark做需求的血淚教訓
Python內部對key的索引是有序的,具體我舉個例子.
In [6]: hash("acc")7
Out[6]: 2
In [7]: hash("abc")7
Out[7]: 4
In [8]: {"acc":"acc","abc":"abc"}
Out[8]: {"abc": "abc", "acc": "acc"}
輸入字典順序是先key"acc"後key"abc",輸出位置就倒了.
當然除了整數hash("key")7的值好像每次重新開一個Python解釋器都會變.所以說可能你的hash("abc")7這個值也會和我的不一樣.
回到你的問題.
In [9]: hash("Wang")7
Out[9]: 1
In [10]: hash("Li")7
Out[10]: 1
In [11]: hash("Ma")7
Out[11]: 5
In [12]: {"Wang": "C", "Li": "B", "Ma": "A"}
Out[12]: {"Li": "B", "Ma": "A", "Wang": "C"}
我現在的字典順序就變了呢.
但是實際上這個返回順序並不重要.
字典是有順序的 但是順序是不定的 不信你可以迭代試試
補充 @靈劍 的回答。cpython3.6的dict實現搬了pypy的實現,是保持順序的。** 但你依然不能把dict當作有序的來使用 **因為dict的標準規定*不保證*有順序,要保證有順序的請用OrderedDict
理論上肯定有序的 你既然有放入的順序 查看肯定就有順序 只是不可以順序的方式看待
字典是無序的,這句話是對的。但是字典的存儲過程卻是按順序的。
字典的存儲背後的邏輯是散列表,也就是稀疏數組。dict初始化之後,Python解釋器會給dict分配一定的空間,往字典里添加是按順序添加的。
但是,如果如果繼續往字典里添加新鍵,有可能會引起Python解釋器對存儲空間的擴容,擴容的過程會新建散列表,然後複製已有的元素到新散列表,這個過程可能會引起散列衝突,導致dict的鍵值對的次序發生變化。
《流暢的Python》一書有關於字典的存儲更為詳細的介紹。
如果不了解散列表,可以查資料。
values 和 keys 保持遍歷時鍵對對應順序一致。
推薦閱讀:
※Mixin是什麼概念?
※如何學習 Python,面對那麼多的標準庫,應該如何?
※Python 在改代碼時怎麼處理縮進問題?
※簡歷中如何證明自己的編程能力?
※怎樣才能寫出 Pythonic 的代碼?
TAG:Python |