2017-09-07 2 views
-5

Haben Sie etwas Array mit verschachtelten Wörterbücher:
data = [{'id':1, 'name':'test'}, {'id':2, 'name':'test'}, ....., {'id':N, 'name':'test'}]Python: Rückkehr als ersten Wert Bedingung verschachtelten Wörterbuch in Array

Versuch ersten id Wert wo name=test zurückzukehren:

val = [x['id'] for x in data if x['name'] == 'test'][0]

erwartetes Ergebnis: val = 1

Aber mit Ausnahme: list index out of range
Was ist los?

+0

Bitte zeigen Sie uns die vollständige Zurückverfolgungs – TerryA

+1

Es bedeutet, es gibt keine dict mit 'name = = "Test" in deiner Liste –

+0

Nächste Methode versuchen –

Antwort

1

Ihr Code funktioniert gut für mich Ihre (leicht bearbeitet) Beispieldaten:

data = [{'id': 1, 'name': 'test'}, {'id': 2, 'name': 'test'}, {'id': 3, 'name': 'test'}] 
val = [x['id'] for x in data if x['name'] == 'test'][0] 

>>> print(val) 
1 

Wenn es jedoch kein Wörterbuch ist einen Namen enthält, der die Zielzeichenfolge entspricht:

>>> val = [x['id'] for x in data if x['name'] == 'blah'][0] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
IndexError: list index out of range 

Diese liegt daran, dass das Listenverständnis eine leere Liste erzeugt, da keine Wörterbücher mit d['name'] auf 'blah' gesetzt sind. Das Indizieren einer leeren Liste führt zur Ausnahme IndexError. Es ist das gleiche, wie dies zu tun:

>>> [][0] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
IndexError: list index out of range 

Ein einfacher Weg, um dieses Problem beheben, die Liste zu überprüfen, bevor es die Indizierung:

matches = [x['id'] for x in data if x['name'] == 'test'] 
val = matches[0] if matches else None 

hier wird angenommen, dass None nicht als verwendet werden der Wert für eine id.

Eine andere, effizientere Art und Weise, wieder unter der Annahme, dass None keine gültige id ist next() mit einem Standardwert zu verwenden:

val = next((x['id'] for x in data if x['name'] == 'test'), None) 

Dieser einen Generator Ausdruck verwendet, der eine ganze Liste vermeidet die Erzeugung der angepassten Wörterbücher enthalten . Stattdessen wird nur über die Liste data iteriert, bis die erste Übereinstimmung gefunden wurde oder die data Liste erschöpft ist.

+0

Alternative Lösung ist 'next' mit Generator Ausdruck zu verwenden, die auch die Konstruktion möglicherweise lange Liste vermeiden:' next ((x ['id'] für x in Daten wenn x ['name'] == 'test'), None) ' – niemmi

+0

@niemmi: Danke. Es sieht so aus, als hätte ich das zu meiner Antwort hinzugefügt, während Sie kommentierten. – mhawke

0
def getFirstMatchingId(data): 
    val = [x['id'] for x in data if x['name'] == 'test'] 
    if len(val) >= 1: 
     val = val[0] 
     print "Matching ID:-->",val 

data = [{'id':1, 'name':'test'}, {'id':2, 'name':'test'}, {'id':3, 'name':'test'}] 
getFirstMatchingId(data) 

data = [{'id':1, 'name':'test1'}, {'id':2, 'name':'test'}, {'id':3, 'name':'test1'}] 
getFirstMatchingId(data) 

data = [{'id':1, 'name':'test1'}, {'id':2, 'name':'test1'}, {'id':3, 'name':'test1'}] 
getFirstMatchingId(data) 

data = [] 
getFirstMatchingId(data) 

Above Programm Ausgabe

Matching ID geben: -> 1 Matching ID: -> 2

Verwandte Themen