web-dev-qa-db-ja.com

宣言されたのと同じ順序でキー/値を保持するにはどうすればいいですか?

私は特定の順序で宣言した辞書を持っていて、それを常にその順序に保ちたいのです。キー/値は、実際にはそれらの値に基づいて順番に並べることはできません。宣言した順番にしたいのです。

だから私は辞書があれば:

d = {'ac': 33, 'gw': 20, 'ap': 102, 'za': 321, 'bs': 10}

それを見たり、繰り返したりしても、その順序ではありません。キー/値を宣言した順序でPythonが明示的な順序を維持するようにする方法はありますか?

267
roflwaffle
from collections import OrderedDict
OrderedDict((Word, True) for Word in words)

含む

OrderedDict([('He', True), ('will', True), ('be', True), ('the', True), ('winner', True)])

値がTrue(またはその他の不変オブジェクト)の場合は、次のものも使用できます。

OrderedDict.fromkeys(words, True)
164
eumiro

理論的な部分を説明するのではなく、簡単な例を挙げます。

>>> from collections import OrderedDict
>>> my_dictionary=OrderedDict()
>>> my_dictionary['foo']=3
>>> my_dictionary['aol']=1
>>> my_dictionary
OrderedDict([('foo', 3), ('aol', 1)])
>>> dict(my_dictionary)
{'foo': 3, 'aol': 1}
157
Mohit Dabas

Python 3.6以降、標準のdict型はデフォルトで挿入順を維持します。

定義する

d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10}

ソースコードにリストされている順序でキーを持つ辞書になるでしょう。

これは、スパースハッシュテーブルに整数を含む単純な配列を使用することによって実現されました。これらの整数は、キーと値のペア(および計算されたハッシュ)を格納する別の配列にインデックスを付けます。後者の配列はたまたま挿入順にアイテムを格納するだけで、全体の組み合わせは実際にはPython 3.5以前で使用されていた実装よりも少ないメモリを使用します。詳細は Raymond Hettingerによるオリジナルのアイデア投稿 を参照してください。

3.6では、これはまだ実装の詳細と見なされていました。 Python 3.6の新機能のドキュメントを参照してください

この新しい実装の順序保持の側面は実装の詳細と考えられており、信頼するべきではありません(これは将来変更される可能性がありますが、言語仕様を変更する前にいくつかのリリースでこの新しい辞書実装を言語で使用することをお勧めします)。現在および将来のすべてのPython実装に対して順序を維持するセマンティクスを強制すること;これは、ランダムな繰り返し順序がまだ有効である古いバージョンの言語、たとえばPython 3.5との後方互換性を維持するのにも役立ちます。

Python 3.7では、この実装の詳細が言語仕様に引き上げられたため、dictはそのバージョン以降と互換性のあるすべてのPython実装で順序を保持することが必須になりました。 BDFLによる発音 を参照してください。

場合によっては、標準のdict型に加えていくつかの追加機能が提供されるため、 collections.OrderedDict()クラス を使用することをお勧めします。 リバーシブル (これは ビューオブジェクト に拡張される)、並べ替えをサポートする( move_to_end()メソッド を介して)などのように。

151
Martijn Pieters

この答えはpython3.7より前のバージョンのPythonに適用されることに注意してください。 CPython 3.6は、ほとんどの場合、実装の詳細として挿入順序を維持します。 Python3.7以降では、実装は準拠するために挿入順序を維持しなければならないと宣言されています


pythonの辞書は順不同です。順序付き辞書が必要な場合は、 collections.OrderedDict を試してください。

OrderedDictがpython 2.7の標準ライブラリに導入されたことに注意してください。あなたが古いバージョンのpythonを持っているならば、あなたは ActiveState で順序付けられた辞書のレシピを見つけることができます。

32
mgilson

辞書は検索を効率的にする順序を使用します、そしてあなたはそれを変えることができません、

オブジェクトのリスト(単純な場合は2要素のTuple、さらにはクラス)を使用して、最後に項目を追加することができます。その後、線形検索を使用してその中の項目を見つけることができます。

あるいは、順序を維持する目的で作成された別のデータ構造を作成または使用することもできます。

11
Fire Lancer

OrderedDictを機能させる方法を見つけようとしているときに、この記事に出会いました。 PyDev for EclipseはOrderedDictをまったく見つけることができなかったので、私は辞書のキー値をTupleにして注文したいと思うことにしました。リストを出力する必要があるときは、Tupleの値を繰り返し処理し、Tupleから辞書に繰り返した「キー」を差し込んで、必要な順序で値を取得しました。

例:

test_dict = dict( val1 = "hi", val2 = "bye", val3 = "huh?", val4 = "what....")
test_Tuple = ( 'val1', 'val2', 'val3', 'val4')
for key in test_Tuple: print(test_dict[key])

それは少し面倒ですが、私は時間を切望しています、そしてそれは私が思い付いた回避策です。

注:他の人が提案したリストのリストのアプローチは、私にはあまり意味がありません。リストは順序付けられ、索引が付けられているからです(そして辞書とは異なる構造でもあります)。

7
smushface

あなたが本当にあなたが辞書でやりたいことをすることはできません。辞書d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10}がすでに作成されています。私はそれがすでに作成された後に整理する方法がないことがわかりました。私がしたことはオブジェクトではなくjsonファイルを作ることでした:

{"ac":33,"gw":20,"ap":102,"za":321,"bs":10}

私は使った:

r = json.load(open('file.json'), object_pairs_hook=OrderedDict)

それから使われる:

print json.dumps(r)

検証します。

6
nealous3

辞書を特定の順序で並べたい場合は、最初の項目がキーになり、2番目の項目が値になり、この例のようになるリストのリストを作成することもできます。

>>> list =[[1,2],[2,3]]
>>> for i in list:
...     print i[0]
...     print i[1]

1
2
2
3
1
pelos
from collections import OrderedDict
list1 = ['k1', 'k2']
list2 = ['v1', 'v2']
new_ordered_dict = OrderedDict(Zip(list1, list2))
print new_ordered_dict
# OrderedDict([('k1', 'v1'), ('k2', 'v2')])
1
user11502624

Djangoプロジェクトを開発するときにも、同様の問題がありました。私は古いバージョンのpythonを実行していたのでOrderedDictを使うことができませんでした。そのための解決策はDjangoのSortedDictクラスを使うことでした。

https://code.djangoproject.com/wiki/SortedDict

例えば。、

from Django.utils.datastructures import SortedDict
d2 = SortedDict()
d2['b'] = 1
d2['a'] = 2
d2['c'] = 3

注:この回答は、もともと2011年からのものです。Pythonバージョン2.7以降にアクセスする場合は、現在標準となっているcollections.OrderedDictにアクセスする必要があります。その多くは、このスレッドで他の人によって提供されています。

1
Evan

一般に、辞書のように振る舞うクラスを設計することができます。主に__contains____getitem____delitem____setitem__などのメソッドを実装することです。そのクラスはあなたが好きな振る舞いをすることができます、例えばキーの上にソートされたイテレータを分割すること...

1
Rasmus Kaj

あなたは私が辞書のためにした同じことをすることができます。

リストと空の辞書を作成します。

dictionary_items = {}
fields = [['Name', 'Himanshu Kanojiya'], ['email id', '[email protected]']]
l = fields[0][0]
m = fields[0][1]
n = fields[1][0]
q = fields[1][1]
dictionary_items[l] = m
dictionary_items[n] = q
print dictionary_items
0

もう1つの選択肢は、Pandas dataframe を使用することです。これは、辞書のような構造で項目の順序とインデックス位置を保証するためです。

0
Ville