12

こんにちは、値のリストを持つキーを持つ順序付けられた辞書が欲しいです。

以下のコードから、キーのリストを含む辞書を取得できましたが、挿入順序がありません。

from collections import defaultdict

keys=['blk','pri','ani']
vals1=['blocking','primary','anim']
vals2=['S1','S2','S3']
dic = defaultdict(list)

i=0

for key in keys:
    dic[key].append(vals1[i])
    dic[key].append(vals2[i])

    i += 1

print dic

次の結果が得られます

defaultdict(<type 'list'>, {'pri': ['primary', 'S2'], 'ani': ['anim', 'S3'], 'blk': ['blocking', 'S1']})

ここで挿入順序を失いました。

Pythonのdefaultdictオブジェクトは定義上順序付けされていないことを私は知っています。

また、値が挿入された順序が必要な場合は、OrderedDictを使用する必要があることを知っています(Python 2.7および3.xで使用可能です)

だから私のコードを以下のように変更しました

以下のコードから、必要なものを取得できました。

from collections import defaultdict,OrderedDict

keys=['blk','pri','ani']
vals1=['blocking','primary','anim']
vals2=['S1','S2','S3']
dic = OrderedDict(defaultdict(list))

i=0

for key in keys:
    dic[key].append(vals1[i])
    dic[key].append(vals2[i])

    i += 1

print dic

そして今、私は以下のエラーを受け取ります

Traceback (most recent call last):
  File "Dict.py", line 18, in <module>
    dic[key].append(vals1[i])
KeyError: 'blk' 

誰かが私が試しているものを手に入れる方法を教えてもらえますか?

4

3 に答える 3

10

「順序付き」および「デフォルト」の動作が本当に必要な場合は、すべてを処理するカスタム辞書クラスを作成すると思います。

from collections import OrderedDict

class DefaultListOrderedDict(OrderedDict):
    def __missing__(self,k):
        self[k] = []
        return self[k]

keys=['blk','pri','ani']
vals1=['blocking','primary','anim']
vals2=['S1','S2','S3']
dic = DefaultListOrderedDict()
for i,key in enumerate(keys):
    dic[key].append(vals1[i])
    dic[key].append(vals2[i])

print dic

これは他のソリューションよりも動作が似ていますdefaultdictが、順序が保持され、実際には多くのコードではありません:)。最後に、__init__(ハードコーディングではなく) 必要な "factory" をユーザーが渡すことができるようにオーバーライドすることもできますlist。これは、興味のある読者のための演習として残しておきます。パイソンはとてもクールです。

于 2012-11-07T07:41:02.167 に答える
3

ラップOrderedDictアラウンドの問題defaultdict(list)は、次のように評価されることです。

  1. の空のインスタンスを作成しますdefaultdict
  2. のインスタンスを作成しOrderedDict、(現在は空) の内容で初期化してdefaultdictから、古いdefaultdictものを破棄します。

これは、あなたが望むように彼らの行動を組み合わせません。

私が見た標準的なイディオムはdict.setdefaultメソッドです。

from collections import OrderedDict

keys=['blk','pri','ani']
vals1=['blocking','primary','anim']
vals2=['S1','S2','S3']
dic = OrderedDict()

i=0

for key in keys:
    dic.setdefault(key, []).append(vals1[i])
    dic.setdefault(key, []).append(vals2[i])

    i += 1

print dic

defaultdict と同様に、これは最初にアクセスしたときに値を作成しますが、少し効率が悪いと思います。

ただし、このアプローチを使用します。

from collections import OrderedDict
dic = OrderedDict(zip(keys, zip(vals1, vals2)))
print dic
于 2012-11-07T07:27:56.733 に答える
2

これを試して:

from collections import OrderedDict

keys=['blk','pri','ani']
vals1=['blocking','primary','anim']
vals2=['S1','S2','S3']
print OrderedDict(zip(keys, zip(vals1, vals2)))
于 2012-11-07T07:24:24.833 に答える