web-dev-qa-db-ja.com

Python:dict内の何かに基づいてリストからdictを取得します

list内の値に基づいて、dict(この場合はdictであるアイテム)内のアイテムを見つけることができる必要があります。処理する必要があるlistの構造は次のようになります。

[
    {
        'title': 'some value',
        'value': 123.4,
        'id': 'an id'
    },
    {
        'title': 'another title',
        'value': 567.8,
        'id': 'another id'
    },
    {
        'title': 'last title',
        'value': 901.2,
        'id': 'yet another id'
    }
]

警告:titleおよびvalueは任意の値(および同じ)にすることができ、idは一意です。

一意のdictに基づいて、このlistからidを取得できる必要があります。ループを使用してこれを実行できることは知っていますが、これは面倒なようで、脳を溶かしたおかげで見られない明白な方法があると感じています。

44
johneth
my_item = next((item for item in my_list if item['id'] == my_unique_id), None)

これは、my_unique_idに一致する最初のアイテムが見つかるまでリストを反復し、その後停止します。 (ジェネレーター式を使用して)中間リストをメモリに保存したり、明示的なループを必要としません。オブジェクトが見つからないというmy_itemNoneに設定します。それはほぼ同じです

for item in my_list:
    if item['id'] == my_unique_id:
        my_item = item
        break
else:
    my_item = None

elseループのfor節は、ループがbreakステートメントで終了していない場合に使用されます。

76
agf

これを複数回行う必要がある場合は、リストでidによってインデックス付けされた辞書を再作成する必要があります。

keys = [item['id'] for item in initial_list]
new_dict = dict(Zip(keys, initial_list)) 

>>>{
    'yet another id': {'id': 'yet another id', 'value': 901.20000000000005, 'title': 'last title'}, 
    'an id': {'id': 'an id', 'value': 123.40000000000001, 'title': 'some value'}, 
    'another id': {'id': 'another id', 'value': 567.79999999999995, 'title': 'another title'}
}

またはagfによって提案されたワンライナーの方法で:

new_dict = dict((item['id'], item) for item in initial_list)
18
Cédric Julien

私のためにiter()でのみ働いた:

my_item = next(iter(item for item in my_list if item['id'] == my_unique_id), None)
1

この目的のために簡単な関数を作成できます:

lVals = [{'title': 'some value', 'value': 123.4,'id': 'an id'},
 {'title': 'another title', 'value': 567.8,'id': 'another id'},
 {'title': 'last title', 'value': 901.2, 'id': 'yet another id'}]

def get_by_id(vals, expId): return next(x for x in vals if x['id'] == expId)

get_by_id(lVals, 'an id')
>>> {'value': 123.4, 'title': 'some value', 'id': 'an id'}
0
In [2]: test_list
Out[2]: 
[{'id': 'an id', 'title': 'some value', 'value': 123.40000000000001},
 {'id': 'another id', 'title': 'another title', 'value': 567.79999999999995},
 {'id': 'yet another id', 'title': 'last title', 'value': 901.20000000000005}]

In [3]: [d for d in test_list if d["id"] == "an id"]
Out[3]: [{'id': 'an id', 'title': 'some value', 'value': 123.40000000000001}]

リスト内包表記を使用する

0
TyrantWave

念のため、辞書のキーに基づいてルックアップ検索が必要な場合。

my_item = next((item for item in my_list if item.has_key(my_unique_key)), None)

0
Kevin Amipara