dict
たくさんのエントリがあるを持っています。そのうちのいくつかだけに興味があります。他のすべてのものを削除する簡単な方法はありますか?
dict
たくさんのエントリがあるを持っています。そのうちのいくつかだけに興味があります。他のすべてのものを削除する簡単な方法はありますか?
回答:
新しい辞書を作成する:
dict_you_want = { your_key: old_dict[your_key] for your_key in your_keys }
辞書内包表記を使用します。
それらがないバージョン(つまり、Python 2.6以前)を使用する場合は、それを作成してくださいdict((your_key, old_dict[your_key]) for ...)
。醜いですが、同じです。
これは、jnnnnnのバージョンとは異なりold_dict
、任意のサイズのs に対して安定したパフォーマンス(your_keysの数にのみ依存)があることに注意してください。速度とメモリの両方の面で。これはジェネレータ式であるため、一度に1つの項目を処理し、old_dictのすべての項目を調べません。
すべてをインプレースで削除:
unwanted = set(keys) - set(your_dict)
for unwanted_key in unwanted: del your_dict[unwanted_key]
old_dict
他の場所にあるバグを示している場所も多くあります。その場合、私は黙って間違った結果よりもエラーを優先します。
少しエレガントな辞書の理解:
foodict = {k: v for k, v in mydict.items() if k.startswith('foo')}
mydict.iteritems()
代わりに使用した場合、おそらく同じパフォーマンスになります。.items()
別のリストを作成します。
Python 2.6の例を次に示します。
>>> a = {1:1, 2:2, 3:3}
>>> dict((key,value) for key, value in a.iteritems() if key == 1)
{1: 1}
フィルター部分はif
ステートメントです。
この方法は、非常に多くのキーのいくつかだけを選択したい場合、delnanの回答よりも遅くなります。
if key in ('x','y','z')
と思いますが、
コード1:
dict = { key: key * 10 for key in range(0, 100) }
d1 = {}
for key, value in dict.items():
if key % 2 == 0:
d1[key] = value
コード2:
dict = { key: key * 10 for key in range(0, 100) }
d2 = {key: value for key, value in dict.items() if key % 2 == 0}
コード3:
dict = { key: key * 10 for key in range(0, 100) }
d3 = { key: dict[key] for key in dict.keys() if key % 2 == 0}
すべてのピースのコードパフォーマンスは、timeitでnumber = 1000を使用して測定され、コードの各ピースについて1000回収集されます。
Python 3.6の場合、3つの方法のdict辞書キーのパフォーマンスはほぼ同じです。Python 2.7の場合、コード3はわずかに高速です。
この1つのライナーラムダは機能するはずです。
dictfilt = lambda x, y: dict([ (i,x[i]) for i in x if i in set(y) ])
次に例を示します。
my_dict = {"a":1,"b":2,"c":3,"d":4}
wanted_keys = ("c","d")
# run it
In [10]: dictfilt(my_dict, wanted_keys)
Out[10]: {'c': 3, 'd': 4}
これは、dictキー(i in x)を反復処理する基本的なリスト理解であり、キーが目的のキーリスト(y)にある場合、タプル(key、value)ペアのリストを出力します。dict()は全体をラップしてdictオブジェクトとして出力します。
set
forを使用する必要がありますwanted_keys
が、それ以外は問題ありません。
dictfilt({'x':['wefwef',52],'y':['iuefiuef','efefij'],'z':['oiejf','iejf']}, ('x','z'))
は{'x': ['wefwef', 52], 'z': ['oiejf', 'iejf']}
意図したとおりに戻ります。
dict={'0':[1,3], '1':[0,2,4], '2':[1,4]}
結果はでした{}
。これは空白の辞書であると想定していました。
foo = {'0':[1,3], '1':[0,2,4], '2':[1,4]}; dictfilt(foo,('0','2'))
、次のようになります。{'0': [1, 3], '2': [1, 4]}
これは意図された結果です
あなたのオリジナルの辞書を考えるorig
と、あなたが興味を持っていることをエントリのセットをkeys
:
filtered = dict(zip(keys, [orig[k] for k in keys]))
これはデルナンの答えほど良くはありませんが、対象となるすべてのPythonバージョンで機能するはずです。ただし、keys
元の辞書に存在する各要素に対して脆弱です。
デルナンが認めた回答に基づく。
必要なキーの1つがold_dictにない場合はどうなりますか?delnanソリューションは、キャッチできるKeyError例外をスローします。それが必要なものでない場合は、次のようにしたいでしょう:
old_dictとwantd_keysのセットの両方で興奮するキーのみを含めます。
old_dict = {'name':"Foobar", 'baz':42}
wanted_keys = ['name', 'age']
new_dict = {k: old_dict[k] for k in set(wanted_keys) & set(old_dict.keys())}
>>> new_dict
{'name': 'Foobar'}
old_dictで設定されていないキーのデフォルト値があります。
default = None
new_dict = {k: old_dict[k] if k in old_dict else default for k in wanted_keys}
>>> new_dict
{'age': None, 'name': 'Foobar'}
{k: old_dict.get(k, default) for k in ...}
この関数はトリックを行います:
def include_keys(dictionary, keys):
"""Filters a dict by only including certain keys."""
key_set = set(keys) & set(dictionary.keys())
return {key: dictionary[key] for key in key_set}
delnanのバージョンと同じように、これは辞書内包表記を使用し、大きな辞書に対して安定したパフォーマンスを発揮します(辞書内のキーの総数ではなく、許可するキーの数にのみ依存します)。
MyGGanのバージョンと同じように、このリストでは、キーのリストに辞書に存在しない可能性のあるキーを含めることができます。
おまけとして、これは逆です。元の特定のキーを除外することで辞書を作成できます。
def exclude_keys(dictionary, keys):
"""Filters a dict by excluding certain keys."""
key_set = set(dictionary.keys()) - set(keys)
return {key: dictionary[key] for key in key_set}
delnanのバージョンとは異なり、操作は適切に行われないため、パフォーマンスは辞書内のキーの数に関連していることに注意してください。ただし、これの利点は、関数が提供された辞書を変更しないことです。
編集:辞書から特定のキーを除外する別の機能を追加しました。
invert
ことを意味するのkeys
か、それともkeys
拒否されるのか」と尋ねた場合、何人が同意するでしょうか。
選択したキーを削除して新しいディクショナリを作成する場合は、ディクショナリ内包を利用できます
。次に例を示します。
d = {
'a' : 1,
'b' : 2,
'c' : 3
}
x = {key:d[key] for key in d.keys() - {'c', 'e'}} # Python 3
y = {key:d[key] for key in set(d.keys()) - {'c', 'e'}} # Python 2.*
# x is {'a': 1, 'b': 2}
# y is {'a': 1, 'b': 2}
別のオプション:
content = dict(k1='foo', k2='nope', k3='bar')
selection = ['k1', 'k3']
filtered = filter(lambda i: i[0] in selection, content.items())
しかし、ではなくからlist
返される(Python 2)またはイテレータ(Python 3)を取得します。 filter()
dict
filtered
でdict
、辞書を取り戻しましょう!
あなたはを使うことができますpython-benedict
、それはdictサブクラスです。
インストール: pip install python-benedict
from benedict import benedict
dict_you_want = benedict(your_dict).subset(keys=['firstname', 'lastname', 'email'])
GitHubのオープンソースです:https : //github.com/fabiocaccamo/python-benedict
免責事項:私はこのライブラリの作者です。