1. ホーム
  2. python

[解決済み] OrderedDict のコンストラクタで初期化する場合、初期データの順番を保持するための正しい方法とは?

2022-05-29 09:53:09

質問

順序付き辞書(OD)を初期化する際に、初期データの順序を保持する正しい方法は何ですか?

from collections import OrderedDict

# Obviously wrong because regular dict loses order
d = OrderedDict({'b':2, 'a':1}) 

# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b',2), ('a', 1)])

# What about using a list comprehension, will 'd' preserve the order of 'l'
l = ['b', 'a', 'c', 'aa']
d = OrderedDict([(i,i) for i in l])

質問です。

  • OrderedDict は、初期化時に渡されたタプルのリスト、タプルのタプル、リストのタプル、リストのリストなどの順番を維持しますか(上記の2つ目の例と3つ目の例)?

  • を検証するためにどのように行くのですか? OrderedDict が実際に秩序を維持しているかどうかを検証するにはどうしたらよいでしょうか?というのも dict は予測できない順序を持つので、もし私のテストベクトルが幸運にも dict の予測できない順序と同じ初期順序を持っていたらどうでしょうか? たとえば、代わりに d = OrderedDict({'b':2, 'a':1}) と書くとします。 d = OrderedDict({'a':1, 'b':2}) と書くと、順序が保たれていると誤って判断してしまうことがあります。この場合、私が調べたところでは dict はアルファベット順に並んでいることがわかりましたが、それが常に正しいとは限りません。データ構造が順序を保持するかどうかを検証するために反例を使うには、テストベクターが壊れるまで繰り返し試す以外に何か信頼できる方法があるでしょうか?

P.S. 私はこれをここに置いておきます。 参照 : "The OrderedDict constructor and update() method both accept keyword arguments, but their order is lost because Python's function call semantics pass-in keyword arguments using a regular unordered dictionary"

P.P.S : 将来、OrderedDictがkwargsの順序も保持するようになることを期待します(例1)。 http://bugs.python.org/issue16991

どのように解決するのですか?

OrderedDictはアクセスできるすべての順序を保持します。 初期化するために順序付けられたデータを渡す唯一の方法は、最後の 2 つの例のように、キーと値のペアのリスト (または、より一般的には iterable) を渡すことです。 リンク先のドキュメントにあるように、キーワード引数やdict引数を渡した場合、OrderedDictはいかなる順序にもアクセスすることができません。

最後の例でリスト内包を使っても何も変わらないことに注意してください。 という違いはありません。 OrderedDict([(i,i) for i in l])OrderedDict([('b', 'b'), ('a', 'a'), ('c', 'c'), ('aa', 'aa')]) . リスト内包が評価され、リストが作成され、それが渡されます。OrderedDictはそれがどのように作成されたのかについては何も知りません。