2011-08-16 5 views
29

에있는 값을 기준으로 list (이 경우 항목은 dict)의 항목을 찾을 수 있어야합니다. 나는이 과정에 필요한 list의 구조는 다음과 같습니다Python : dict 내부의 내용을 기반으로 목록에서 사전을 가져옵니다.

[ 
    { 
     '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은 고유해야합니다.

listid을 기준으로 dict에서 얻을 수 있어야합니다. 나는 이것이 루프의 사용을 통해 이루어질 수 있다는 것을 알고 있지만, 이것은 성가신 것처럼 보입니다. 그리고 이것을하는 명백한 방법이 있다는 느낌이 들었습니다. 뇌가 녹아서 고맙습니다.

답변

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

my_unique_id 일치 첫 번째 항목이 발견 될 때까지리스트를 이러한 반복은 다음 멈춘다. 생성기 표현식을 사용하여 중간 목록을 메모리에 저장하지 않거나 명시 적 루프가 필요합니다. 객체가없는 my_item ~ None을 설정합니다. 약 루프가 break 문에 의해 종료되지 않은 경우 for 루프에

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

else 절을 사용하는 동일합니다.

+1

@agf 일치 항목이 여러 개인 경우 목록 (일치하는 딕트 목록)에서 추출 하시겠습니까? – Augiwan

+1

@UGS 전체 목록을 스캔하고 결과 목록을 작성해야하며 첫 번째 일치 항목을 찾는 것만이 아니라 '[[id'] 항목이 있으면 [item for my_list item for item] ] == my_unique_id]'. – agf

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

이것은 일치 항목을 찾은 후 목록을 계속 사용합니다. – agf

+0

ID가 고유해야한다면 len()을 사용하면 고유 ID가 아닌 것으로 표시됩니다 – TyrantWave

+0

ID가 고유하지 않은 것은 아닙니다. 'len (my_list)'비교 또는'len (my_list) // 2' 비교. 귀하의 버전은 필요한만큼 평균 2 배의 작업을 수행합니다. – agf

15

이 여러 번해야하는 경우에, 당신은 당신의 목록 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) 
+2

'new_dict = dict ((item_ [id '], item) initial_list에있는 항목에 대해서)'... 중간 목록을 만들고 나서'zip'을 만드는 이유는 무엇입니까? – agf

0

이 목적을 위해 간단한 기능을 만들 수 있습니다 :

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'} 
관련 문제