0

他の辞書と比較する必要がある一連の辞書を含むリストがあります。

次の形式があります (キーと値に特定の形式やパターンはありません。これらはランダムに選択された例です)。

list1 = [
    {'X1': 'Q587', 'X2': 'Q67G7', ...},
    {'AB1': 'P5K7', 'CB2': 'P678', ...},
    {'B1': 'P6H78', 'C2': 'BAA5', ...}]

dict1 = {
    'X1': set([B00001,B00020,B00010]),
    'AB1': set([B00001,B00007,B00003]), 
    'C2': set([B00001,B00002,B00003]),  ...
}

私が今欲しいのは、list1 の辞書の値をキーとする新しい辞書です。および値として dict1 の値。そしてこれは、比較された辞書でキーが交差する場合のみです。

私は次の方法でこれを行いました:

nDicts = len(list1)
resultDict = {}

    for key in range(0,nDicts):
            for x in list1[key].keys():
                if x in dict1.keys():
                    resultDict.update{list1[key][x]:dict1[x]}
                    print resultDict

目的の出力は次の形式である必要があります。

resulDict = {
        'Q587': set([B00001,B00020,B00010]),
        'P5K7': set([B00001,B00007,B00003]), 
        'BAA5': set([B00001,B00002,B00003]),  ...
    }

これは機能しますが、データ量が非常に多いため、これには永遠に時間がかかります。これを行うより良い方法はありますか?

編集: 入力値を少し変更しました。重要なのは、list1 内の辞書と dict1 内の辞書の間で交差するキーだけです。

4

3 に答える 3

1

交差点を設定することで、操作を簡素化および最適化できます。dict.viewkeys()Python 2.7以降、辞書はメソッドを使用してキーをセットとして表すことができますdict.keys()。Python 3 では次のようになります。

resultDict = {}

for d in list1:
    for sharedkey in d.viewkeys() & dict1:
        resultDict[d[sharedkey]] = dict1[sharedkey]

これは、辞書内包表記に変えることもできます:

resultDict = {d[sharedkey]: dict1[sharedkey] 
              for d in list1 for sharedkey in d.viewkeys() & dict1}

ここでは、共有キーごとに新しい辞書ではなく、結果の辞書が1 つ必要であると想定しています。

サンプル入力のデモ:

>>> list1 = [
...     {'X1': 'AAA1', 'X2': 'BAA5'},
...     {'AB1': 'AAA1', 'CB2': 'BAA5'},
...     {'B1': 'AAA1', 'C2': 'BAA5'},
... ]
>>> dict1 = {
...     'X1': set(['B00001', 'B00002', 'B00003']),
...     'AB1': set(['B00001', 'B00002', 'B00003']),
... }
>>> {d[sharedkey]: dict1[sharedkey] 
...  for d in list1 for sharedkey in d.viewkeys() & dict1}
{'AAA1': set(['B00001', 'B00002', 'B00003'])}

X1 と の両方が の辞書と AB1共有されていることに注意してくださいlist1。ただし、どちらの場合も、結果のキーはAAA1です。これらのうちの 1 つのみ (最後の試合) が勝ちますが、両方の値dict1がまったく同じであるため、この場合はオッズがありません。

の辞書ごとに個別の辞書が必要な場合は、ループを外list1に移動します。for d in list1:

for d in list1:
    resultDict = {d[sharedkey]: dict1[sharedkey] for sharedkey in d.viewkeys() & dict1}
    if resultDict:  # can be empty
        print resultDict

共有キーごとに 1 つの辞書が本当に必要な場合は、別のループを外に移動します。

for d in list1:
    for sharedkey in d.viewkeys() & dict1:
        resultDict = {d[sharedkey]: dict1[sharedkey]}
        print resultDict
于 2013-10-03T20:03:01.590 に答える
1

Python 2.xのkeysメソッドは、すべてのキーのコピーを含むリストを作成します。これを行うのは、各 dict だけではありませlist1ん (おそらく大したことではありませんが、データを知らずに確実に知ることは困難です)。 、しかし、何度も何度もやっていdict1ます。

その上in、リストのテストを行うには、一致する値が見つかるまでリスト内の各値をチェックする必要があるため、長い時間がかかりますがin、辞書のテストは検索するだけなので、ほぼ瞬時に実行できます。ハッシュ値。

どちらも実際には完全に不要です. dictkeysを反復するとキーが順番に返されます (順序は指定されていませんが、 を呼び出す場合も同じですkeys()) 。したがって、それらを削除するだけでも同じことが行われますが、よりシンプルで高速になり、メモリの使用量が少なくなります。そう:inkeys()

for key in range(0,nDicts):
    for x in list1[key]:
        if x in dict1:
            resultDict={list1[key][x]:dict1[x]}
            print resultDict

これを単純化する方法もいくつかありますが、おそらくパフォーマンスはそれほど向上しませんが、それでも実行する価値はあります。

list1すべてのインデックスの巨大なリストを構築してそれを繰り返す代わりに、直接繰り返すことができます。

for list1_dict in list1:
    for x in list1_dict:
        if x in dict1:
            resultDict = {list_dict[x]: dict1[x]}
            print resultDict

また、1 つのステップでキーと値を取得できます。

for list1_dict in list1:
    for k, v in list1_dict.iteritems():
        if k in dict1:
            resultDict = {v: dict1[k]}
            print resultDict

また、ほとんどの値が見つかると予想される場合は、最初に値を確認してから検索するのに、単に検索して失敗を処理しようとする場合の約 2 倍の時間がかかります。(ただし、ほとんどの値が見つからない場合、これは当てはまりません。) したがって、次のようになります。

for list1_dict in list1:
    for k, v in list1_dict.iteritems():
        try:
            resultDict = {v: dict1[k]}
            print resultDict
        except KeyError:
            pass
于 2013-10-03T19:56:42.087 に答える
0
#!/usr/bin/env python

list1 = [

    {'X1': 'AAA1', 'X2': 'BAA5'},
    {'AB1': 'AAA1', 'CB2': 'BAA5'},
    {'B1': 'AAA1', 'C2': 'BAA5'}

    ]


dict1 = {
    'X1': set(['B00001','B00002','B00003']),
    'AB1': set(['B00001','B00002','B00003'])
}    


g = ( k.iteritems() for k in list1)
ite = ((a,b) for i in g for a,b in i if dict1.has_key(a))

d = dict(ite)            
print d          
于 2013-10-03T20:03:21.230 に答える