2013-12-10 22 views
0

因此,我意識到字典是無序數據類型,但是如果您有字典,可以調用d.keys()並獲取一個有序數據類型的列表。該訂單如何確定?如果我做這樣的事情如何在python字典中確定鍵的順序

d = {1: 2, 3: 4, 5: 6} 
d[4] = 7 
d[10] = 2 

爲什麼運行起來也()返回[1, 10, 3, 4, 5]

+4

哈希函數 –

+0

http://stackoverflow.com/questions/14863536/iterate-through-python-dictionary-by-keys-in-order – 2013-12-10 19:59:42

+0

http://docs.python.org/2/library/ stdtypes.html#dict.items:「鍵和值以非隨機的任意順序列出,在Python實現中有所不同,並且取決於字典的插入和刪除歷史 如果items(),keys() ,值(),iteritems(),iterkeys()和itervalues()被調用時不需要對字典進行中間修改,這些列表將直接對應。「 –

回答

0

詞典沒有排序,您必須對鍵進行排序,如果您想要排序它們。

2

指數是hash tables。他們明確沒有排序,這意味着你的代碼不應該依賴於他們有任何特定的順序。

返回鍵的順序取決於很多事情,其中​​包括插入它們的順序,插入它們時的字典大小,是否刪除了某些東西,函數用於計算每個鍵的散列值以及你正在使用的Python的實現(Python,Jython,IronPython和PyPy都可能在完全相同的代碼上給出不同的結果)。

如果你想要一個有序的字典(其中的鍵保持你插入它們的順序),看看https://pypi.python.org/pypi/odict(它在Python 2.7以後的stdlib中)。

+2

詳細說明,它在標準庫中是'collections.OrderedDict'。 – kindall

+1

有趣的是,文檔從來沒有說過,它保證是一個哈希表。很難想象任何其他的數據結構都能滿足'dict'類型的保證(O(1)搜索,引發不可散列鍵等)。也許你可以在布隆過濾器上創建一個? – abarnert

4

Python語言沒有定義鍵的順序;任何實現都可以使用它想要的任何順序。 The documentation說:

鍵和值以非隨機的任意順序迭代,跨Python實現而變化,並且取決於字典的插入和刪除歷史。

(在文檔中的措辭和位置是在2.x中略有不同,但這個想法是一樣的。)

如果你對CPython的執行情況,特別詢問,細節有所改變了兩次在2.x和3.4之間,所以你不得不問一個特定的版本,而不是一般的CPython。正如馬克斯諾埃爾的答案所暗示的那樣,這些細節非常複雜。

但真正:

  • 它不應該對任何代碼的關係。
  • 如果確實很重要,那麼您可能需要閱讀您關心的實現的源代碼,因爲它們中的大多數不會記錄它。例如,在CPython中,請參閱dictobject.c(您需要的版本)。

的一件事,你可以指望的是,如果你多次重複相同的單詞而不改變它,順序將是一致的。

如果您想要像字典一樣操作但保留鍵的插入順序,請參見標準庫中的collections.OrderedDict。如果你的行爲像一個字典,但按照排序順序保存鍵,你可能需要一個基於樹的結構;有多種第三方選項可供選擇,如blist.sorteddictbintrees.FastRBTree

0

它只是隨機的,不同於發佈版本。根本不應該有任何固定的d.keys()命令。事實上,在2.x d.keys()返回一個列表給你的錯覺,有一些內部的順序。但它不存在。請注意,在3.x d.keys()返回一個視圖objet,這是一個可迭代的,而不是列表。你必須使用列表(d.keys())來創建一個真正的列表。

+0

文檔明確指出它不是隨機的。如果您需要隨機排序(例如,爲了加密或統計目的),字典不會這樣做。此外,關鍵的觀點與列表的事情是一個紅鯡魚;關鍵視圖給出了與列表(或者你在2.x中從'iterkeys'獲得的'keyiterator'對象)相同的內部排序錯覺。 – abarnert

+0

以abarnert:你是對的。當我說'隨機'時,我的意思是說它是由很多因素決定的,不應該依賴它。 –

+0

這篇文檔(以及大部分已經在這裏寫下的答案)都將其描述爲「任意[但]非隨機」。稱這種「隨機」具有誤導性。 – abarnert