web-dev-qa-db-ja.com

キーに特定の文字列が含まれるpython辞書内のアイテムをフィルターします

私はpythonで何かを開発しているCコーダーです。私はCで次のことをする方法を知っています(したがって、Pythonに適用されるCのようなロジックで)が、それを行う「Python」の方法は何ですか?.

辞書dがあり、アイテムのサブセットを操作したいのですが、キー(文字列)の人だけが特定のサブ文字列を含んでいます。

つまり、Cロジックは次のようになります。

for key in d:
    if filter_string in key:
        # do something
    else
        # do nothing, continue

pythonバージョンは次のようになると想像しています

filtered_dict = crazy_python_syntax(d, substring)
for key,value in filtered_dict.iteritems():
    # do something

辞書のフィルタリングに関する多くの記事をここで見つけましたが、これに関連する記事は見つかりませんでした。

辞書がネストされておらず、python 2.7を使用しています

76
memo

dict内包表記

filtered_dict = {k:v for k,v in d.iteritems() if filter_string in k}

あなたがそれを見ると、それは英語のようにかなりよく読めるので、それは自明であるべきです。

この構文には、Python 2.7以降が必要です。

Python 3には、 dict.items() のみがあり、iteritems()ではないため、以下を使用します。

filtered_dict = {k:v for (k,v) in d.items() if filter_string in k}
151

最も読みやすく、保守が容易なものを探してください。 1行で書き出すことができるからといって、そうすべきだとは限りません。あなたの既存のソリューションは、値のルックアップをスキップするためにiteritemsを使用する以外に私が使用するものに近く、それらを避けることができる場合、ネストされたifsは嫌いです:

for key, val in d.iteritems():
    if filter_string not in key:
        continue
    # do something

ただし、フィルター処理されたdictを繰り返し処理できるようにする場合は、フィルター処理されたdictを作成してそれを反復処理する2段階のプロセスは行わず、代わりにジェネレーターを使用します。発電機?

まず、ジェネレーターを作成します。適切な設計により、再利用可能にするために十分に抽象化する必要があります。

# The implementation of my generator may look vaguely familiar, no?
def filter_dict(d, filter_string):
    for key, val in d.iteritems():
        if filter_string not in key:
            continue
        yield key, val

そして、ジェネレーターを使用して、単純でわかりやすいコードで問題をきれいに解決できます。

for key, val in filter_dict(d, some_string):
    # do something

要するに、ジェネレーターは素晴らしいです。

15
Brendan F
input = {"A":"a", "B":"b", "C":"c"}
output = {k:v for (k,v) in input.items() if key_satifies_condition(k)}
8
jspurim

Jonathonは、 his answer でディクテーションを使用したアプローチを提供しました。ここでは、何かをする部分を扱うアプローチを示します。

辞書の値を使って何かをしたい場合は、辞書の理解はまったく必要ありません。

私はiteritems(を使用しています。なぜならあなたは python-2.7で質問にタグを付けたからです

results = map(some_function, [(k,v) for k,v in a_dict.iteritems() if 'foo' in k])

これで、結果は、some_functionが辞書の各キー/値ペアに適用され、キーにfooが含まれるリストになります。

値を処理し、キーを無視する場合は、リストの内包表記を変更するだけです。

results = map(some_function, [v for k,v in a_dict.iteritems() if 'foo' in k])

some_functionは任意の呼び出し可能オブジェクトにすることができるため、ラムダも機能します。

results = map(lambda x: x*2, [v for k,v in a_dict.iteritems() if 'foo' in k])

generator expressionもマップに渡すことができるため、実際には内部リストは必要ありません。

>>> map(lambda a: a[0]*a[1], ((k,v) for k,v in {2:2, 3:2}.iteritems() if k == 2))
[4]
7
Burhan Khalid

組み込みの filter function を使用して、特定の条件に基づいて辞書、リストなどをフィルタリングできます。

filtered_dict = dict(filter(lambda item: filter_str in item[0], d.items()))

利点は、さまざまなデータ構造に使用できることです。

6
Pulkit