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'
}
]

注意: titlevalue可以是任意值(和相同值) ,id将是唯一的。

我需要能够得到一个 dict从这个 list基于一个独特的 id。我知道这可以通过使用循环来完成,但是这似乎很麻烦,我有一种感觉,有一种显而易见的方法可以做到这一点,多亏了大脑的融化,我没有看到这种方法。

83134 次浏览
my_item = next((item for item in my_list if item['id'] == my_unique_id), None)

This iterates through the list until it finds the first item matching my_unique_id, then stops. It doesn't store any intermediate lists in memory (by using a generator expression) or require an explicit loop. It sets my_item to None of no object is found. It's approximately the same as

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

else clauses on for loops are used when the loop is not ended by a break statement.

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}]

Use list comprehension

If you have to do this multiple times, you should recreate a dictionnary indexed by id with your list :

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'}
}

or in a one-liner way as suggested by agf :

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

You can create a simple function for this purpose:

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'}

Worked only with iter() for me:

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

Just in case, if you want lookup search on the basis of the key of a dictionary.

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

For 3.0+, has_key() has been deprecated. Instead use in:

my_item = next((item for item in mylist if 'my_unique_key' in item), None)

https://docs.python.org/3.0/whatsnew/3.0.html#builtins

I used this, since my colleagues are probably more able to understand what's going on when I do this compared to some other solutions provided here:

[item for item in item_list if item['id'] == my_unique_id][0]

And since it's used in a test, I think the extra memory usage isn't too big of a deal (but please correct me if I am wrong). There's only 8 items in the list in my case.