私は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を使用しています
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}
最も読みやすく、保守が容易なものを探してください。 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
要するに、ジェネレーターは素晴らしいです。
input = {"A":"a", "B":"b", "C":"c"}
output = {k:v for (k,v) in input.items() if key_satifies_condition(k)}
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]
組み込みの filter function を使用して、特定の条件に基づいて辞書、リストなどをフィルタリングできます。
filtered_dict = dict(filter(lambda item: filter_str in item[0], d.items()))
利点は、さまざまなデータ構造に使用できることです。