簡體   English   中英

Python OrderedDict迭代

[英]Python OrderedDict iteration

為什么我的python OrderedDict被初始化為'亂序'?

這里的解決方案不如解釋那么有趣。 這里有些東西,我只是沒有得到,也許擴張會幫助別人和我。

>>> from collections import OrderedDict

>>> spam = OrderedDict(s = (1, 2), p = (3, 4), a = (5, 6), m = (7, 8))

>>> spam
OrderedDict([('a', (5, 6)), ('p', (3, 4)), ('s', (1, 2)), ('m', (7, 8))])

>>> for key in spam.keys():
...    print key    
...
#  this is 'ordered' but not the order I wanted....
a
p
s
m

# I was expecting (and wanting):
s
p
a
m

來自文檔

OrderedDict構造函數和update()方法都接受關鍵字參數,但它們的順序丟失,因為Python的函數使用常規無序字典調用語義傳入關鍵字參數。

所以初始化會丟失排序,因為它基本上是用**kwargs調用構造函數。

編輯:解決方案而言 (不僅僅是解釋 ) - 如OP的評論所指出的那樣,傳入單個元組列表起作用:

>>> from collections import OrderedDict
>>> spam = OrderedDict([('s',(1,2)),('p',(3,4)),('a',(5,6)),('m',(7,8))])
>>> for key in spam:
...     print(key)
...
s
p
a
m
>>> for key in spam.keys():
...     print(key)
...
s
p
a
m

這是因為它只獲得一個參數,一個列表。

@Chris Krycho很好地解釋了為什么失敗了。

如果你查看OrderedDict的repr(),你會得到一個如何從頭開始傳遞順序的提示:你需要使用(鍵,值)對的列表來保持列表給出的鍵的順序。

這是我之前做的一個:

>>> from collections import OrderedDict
>>> spamher = OrderedDict(s=6, p=5, a=4, m=3, h=2, e=1, r=0)
>>> spamher
OrderedDict([('h', 2), ('m', 3), ('r', 0), ('s', 6), ('p', 5), ('a', 4), ('e', 1)])
>>> 
>>> list(spamher.keys())
['h', 'm', 'r', 's', 'p', 'a', 'e']
>>> 
>>> spamher = OrderedDict([('s', 6), ('p', 5), ('a', 4), ('m', 3), ('h', 2), ('e', 1), ('r', 0)])
>>> list(spamher.keys())
['s', 'p', 'a', 'm', 'h', 'e', 'r']
>>> 

(正巧是在Python 3.3.0你原來的例子spam保存在從一開始就它們原來的順序按鍵。我改spamher得到arounf這一點)。

正如其他 答案所提到的,嘗試將dict傳遞給OrderedDict或使用關鍵字參數不會保留順序。 傳遞元組有點難看,這就是Python。 它應該是美麗的。

您可以使用 AB __getitem__上一類以具有類似字典的語法創建OrderedDict“文字”:

from collections import OrderedDict
class OD(object):
    """This class provides a nice way to create OrderedDict "literals"."""
    def __getitem__(self, slices):
        if not isinstance(slices, tuple):
            slices = slices,
        return OrderedDict((slice.start, slice.stop) for slice in slices)
# Create a single instance; we don't ever need to refer to the class.
OD = OD()

現在您可以使用類似dict的語法來創建OrderedDict:

spam = OD['s': (1, 2), 
          'p': (3, 4), 
          'a': (5, 6), 
          'm': (7, 8)]
assert(''.join(spam.keys()) == 'spam')

這是有效的,因為在方括號內,Python創建切片文字,如果你稍微眯一下,它恰好看起來像dict語法。

OD類可以從錯誤檢查中受益,但這表明它是如何工作的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM