17

次のようなリストがあります。

l1 = ['200:200', '90:728']

次のような辞書があります。

d1 = {'200:200':{'foo':'bar'},'300:300':{'foo':'bar'}}

キーだけがl1にある辞書を除外する必要があります。辞書は次のようになります。

result = {'200:200':{'foo':'bar'}}

本質的には、dict のサブセクションを返しながら、リストと dict のキーの共通部分です。

大規模なセットで時間が問題になる場合、これを効率的に行うにはどうすればよいですか?

ありがとう

4

6 に答える 6

27

次のコードを使用できます。

keys = set(l1).intersection(set(d1.keys()))
result = {k:d1[k] for k in keys}

編集:コメント者が示唆しているように、Python 2.xでは最初の行を次のように置き換えることができます:

keys = set(l1).intersection(d1)

そして Python 3.x では:

keys = d1.keys() & l1
于 2012-06-22T14:02:46.770 に答える
5

3.x では、これは次のように単純です。

>>> {k: d1[k] for k in (d1.keys() & l1)}
{'200:200': {'foo': 'bar'}}

dict.viewkeys()2.7 では、この機能を再作成するために使用できます。

>>> {k: d1[k] for k in (d1.viewkeys() & l1)}
{'200:200': {'foo': 'bar'}}

2.x の古いバージョンでは、少し冗長です。

>>> {k: d1[k] for k in (set(d1).intersection(l1))}
{'200:200': {'foo': 'bar'}}
于 2012-06-22T14:08:15.350 に答える
4

各ソリューションのパフォーマンスについてはわかりませんが、次のようにします。

{k: v for k, v in d1.items() if k in l1}
于 2012-06-22T14:09:07.227 に答える
0

メモリの割り当てと割り当て解除によってこのプロセスに時間がかかりすぎる場合は、 itertools が助けになります。

import itertools
result = {dict_key:d1[dict_key] for dict_key in itertools.ifilter(lambda list_item: list_item in d1, l1) }

これにより、新しいコレクション全体に不必要にメモリが割り当てられることはなく、l1 は簡単にリストではなく反復子になる可能性があります。

于 2012-06-22T14:28:47.397 に答える
0

dict コンストラクターでリスト内包表記を使用できます。

result = dict([(k,d1[k]) for k in l1 if k in d1])

重複したキーの削除が心配な場合は、最初に l1 をセットにします。

result = dict([(k,d1[k]) for k in set(l1) if k in d1])
于 2012-06-22T14:06:06.230 に答える
0

効率的と定義する. とにかく、これが私がすることです。遅すぎる場合は、おそらく Cython に移動します。

s1 = set(l1)
s2 = set(d1.keys())
s3 = s1 & s2
# now you can access d1 using only keys in s3, or construct a new dict if you like
d2 = dict([(k,d1[k]) for k in s3])
于 2012-06-22T14:15:18.403 に答える