30

私の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
4

3 に答える 3

17

@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 v3.3.0 ではspam、キーを最初から元の順序で保持していた元の例がありました。spamherこれを回避するために に変更しました)。

于 2013-05-14T23:45:59.017 に答える
4

回答で述べたように、dict を OrderedDict に渡そうとしたり、キーワード引数を使用したりしても、順序は保持されません。ただし、タプルを渡すのはちょっと面倒です。これは Python です。それは美しいはずです。

OrderedDict「リテラル」を作成するための辞書のような構文を使用するために、クラスでabを使用できます。__getitem__

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クラスはエラー チェックの恩恵を受ける可能性がありますが、これはどのように機能するかを示しています。

于 2015-12-16T19:16:05.320 に答える