1. 程式人生 > >python裡字典是無序的

python裡字典是無序的

關於 Python 字典的 values() 方法返回值的順序?

dict_mark = {'Wang': 'C', 'Li': 'B', 'Ma': 'A'}
s = ''
for c in dict_mark.values():
    s += c
print(s)

關於這個字典打印出來一直是 CBA 的順序,可是字典不是應該無序嗎?stackoverflow的前輩們的答案我看的一知半解,能否請教知友們呢?

問題地址

關注者

38

被瀏覽

8,727

關注問題寫回答

​新增評論

​分享

​邀請回答

收起

12 個回答

預設排序​

廖雪峰

廖雪峰

43 人贊同了該回答

規範是指dict遍歷是不保證順序的,但一定保證每個元素都被遍歷一次

實現可以是無序,也可以是有序,都符合規範

Py3.5是無序的,3.6是有序的,但不能說dict就是有序的,因為如果3.7改成無序的也是正確的實現。

如果要使用有序dict,必須用OrderedDict

​贊同 43​​10 條評論

​分享

​收藏​感謝

Coldwings

9 人贊同了該回答

如果按照語言規範來看,Python的規範裡沒有說明Dict是一個有序的型別。換句話說,dict就是無序的,因為語言規範不保證它按照什麼順序出來。要有序,請使用OrderedDict。

但是無序不是說每次輸出結果都不同,無序只是指結果不保證一定與插入順序一致而已。

CPython 3.6裡對dict有個新的實現,使得字典內部儲存的順序不僅僅與key有關,還與插入順序有關。但是有關並不代表它就一定按照插入順序依次出現(似乎當字典實現在記憶體中進行擴充套件的時候就可能造成結果不一致),只不過表示如果key相同,插入順序相同,那麼結果也是相同的。

在此之前,用values和keys方法取到的list僅與key(準確的說是key的__hash__)有關而與插入順序無關。

​贊同 9​​4 條評論

​分享

​收藏​感謝

靈劍

靈劍

21 人贊同了該回答

無序的不代表隨機的,也不代表每次都是隨機的,這些詞有細微的差異。無序的只是說,你不該對順序有任何假定,既不能假定有確定順序,也不能假定沒有確定順序。

​贊同 21​​6 條評論

​分享

​收藏​感謝

Pegasus Wang

知乎 Python 後端工程師,Pythonista and Vimer

1 人贊同了該回答

你看下 dict 的 CPython hash 實現就瞭解了

​贊同 1​​新增評論

​分享

​收藏​感謝

Revive

碼農 / 死宅 / 玩家

1 人贊同了該回答

一般語言裡的dict結構只是表面上說自己是無序的,實際上根據內部實現會有自己的一套順序,只是這個順序可能比較古怪,比較混沌,比較沒有統一標準,甚至可能以後實現變了順序也會變,所以設計者也不想告訴你究竟是個什麼順序,但是每次讀出來都會根據這個順序出。
不過也有比較奇葩的語言每次讀出來的順序都不一樣,比如說golang。

​贊同 1​​新增評論

​分享

​收藏​感謝

李強

李強

1 人贊同了該回答

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'}

我現在的字典順序就變了呢.

但是實際上這個返回順序並不重要.

​贊同 1​​新增評論

​分享

​收藏​感謝收起​

綾波limbo

我愛python一輩子

2 人贊同了該回答

沒有順序,包括.keys取鍵,.values取值,字典無序儲存不是逗你玩的,不管你在命令列裡輸出多少次一樣的順序都不要上當!!!
如果要取字典順序,請你老老實實用ordereddict!!
這是我有一次在spark做需求的血淚教訓

​贊同 2​​2 條評論

​分享

​收藏​感謝

梧桐

梧桐

答非所問的 見一個舉報一個 呵呵 繼續抖機靈給我看

字典是有順序的 但是順序是不定的 不信你可以迭代試試

​贊同​​新增評論

​分享

​收藏​感謝

Tux ZZ

Tux ZZ

Nothing-to-research Researcher

補充 

@靈劍

 的回答。
cpython3.6的dict實現搬了pypy的實現,是保持順序的。
** 但你依然不能把dict當作有序的來使用 **
因為dict的標準規定*不保證*有順序,要保證有順序的請用OrderedDict

​贊同​​新增評論

​分享

​收藏​感謝

ShengCiun Liang

反對任何形式的平權

理論上肯定有序的 你既然有放入的順序 檢視肯定就有順序 只是不可以順序的方式看待

​贊同​​新增評論

​分享

​收藏​感謝

陳子坤

陳子坤

結構工程師,Python,Go, 大資料, WEB後端

字典是無序的,這句話是對的。但是字典的儲存過程卻是按順序的。

字典的儲存背後的邏輯是散列表,也就是稀疏陣列。dict初始化之後,Python直譯器會給dict分配一定的空間,往字典裡新增是按順序新增的。

但是,如果如果繼續往字典裡新增新鍵,有可能會引起Python直譯器對儲存空間的擴容,擴容的過程會新建散列表,然後複製已有的元素到新散列表,這個過程可能會引起雜湊衝突,導致dict的鍵值對的次序發生變化。

《流暢的Python》一書有關於字典的儲存更為詳細的介紹。

如果不瞭解散列表,可以查資料。

​贊同​​新增評論

​分享

​收藏​感謝匿名使用者

匿名使用者

values 和 keys 保持遍歷時鍵對對應順序一致。