Python: получить диктат из списка на основе чего-то внутри диктанта - PullRequest
40 голосов
/ 16 августа 2011

Мне нужно иметь возможность найти элемент в 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. Я знаю, что это можно сделать с помощью циклов, но это кажется громоздким, и у меня есть ощущение, что есть очевидный способ сделать это, которого я не вижу благодаря расплавлению мозга.

Ответы [ 6 ]

71 голосов
/ 16 августа 2011
my_item = next((item for item in my_list if item['id'] == my_unique_id), None)

Эта функция перебирает список, пока не найдет первый элемент, соответствующий my_unique_id, а затем остановится. Он не хранит промежуточные списки в памяти (с помощью выражения генератора) и не требует явного цикла. Устанавливает my_item в None, если объект не найден. Это примерно так же, как

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

else предложения для циклов for используются, когда цикл не заканчивается оператором break.

17 голосов
/ 16 августа 2011

Если вам нужно сделать это несколько раз, вы должны воссоздать словарь, проиндексированный по 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)
1 голос
/ 11 апреля 2019

работал только с iter() для меня:

my_item = next(iter(item for item in my_list if item['id'] == my_unique_id), None)
0 голосов
/ 06 июня 2019

На всякий случай, если вы хотите выполнить поиск по ключу словаря.

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

0 голосов
/ 16 августа 2011

Для этого вы можете создать простую функцию:

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 голосов
/ 16 августа 2011
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}]

Использовать понимание списка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...