2017-07-04 8 views
1

Ich habe eine Liste von Namen Tupeln:Python: Überprüfen Sie, ob Liste benannter Tupel enthält bestimmte Attributwert

from collections import namedtuple 

T = namedtuple('T', ['attr1', 'attr2', 'attr3', 'attr4']) 
t1 = T('T1', 1, '1234', 'XYZ') 
t2 = T('T2', 2, '1254', 'ABC') 
t3 = T('T2', 2, '1264', 'DEF') 
l = [t1, t2, t3] 

Ich möchte überprüfen, ob ein Element in der Liste vorhanden ist T wo attr1 = 'T2'.

Prüfen, ob die Liste enthält, ein solches Element, indem Sie:

any(x for x in l if x.attr1 == 'T2') 

liefert nur die Information, ob eine solche namedtuple in der Liste enthalten ist oder nicht.
Ich möchte dieses namedtuple auch von der Liste knallen lassen.
Eine Möglichkeit, es zu tun ist:

if any(x for x in l if x.attr1 == 'T2'): 
    result = [x for x in l if x.attr1 == 'T2'].pop() 

Allerdings habe ich diese Lösung nicht gefällt, da ich l zweimal über die Liste bin Looping.

Gibt es einen besseren/eleganteren Weg dies zu tun?

+1

nicht direkt eine Antwort, aber die üblichen 'any' Ausdruck für die Prüfung der Existenz eines solchen Elements wäre' any (x.attr1 == ' T2 'für x in l) ', nicht was du hast. Was Sie tun, ist, dass Sie sich unbeabsichtigt auf die Tatsache verlassen, dass Ihre benannten Tupel als wahr betrachtet werden, wenn sie als Boolean behandelt werden. In der Tat ist das Genexp, das du geschrieben hast, besser geeignet, um ein passendes Nametuple zu extrahieren als das Existenzen zu testen! – user2357112

Antwort

2

Wie wäre es mit einer Old-School-Schleife? Einfach, elegant und nur einmal.

for x in l: 
    if x.attr1 == 'T2': 
     break 

result = x 
1

Oder Sie verwenden next:

try: 
    result = next(t for t in l if t.attr1 == 'T2') 
except StopIteration: 
    result = None 

result 
# T(attr1='T2', attr2=2, attr3='1254', attr4='ABC') 
+0

Wie 'result = next ((t für t in l wenn t.attr1 == 'T5'), None)', nur länger. Mit bloßem 'except' ist auch eine schlechte Idee. – vaultah

+0

@Psidom Ich habe es vor allem deshalb abgelehnt, weil deine Antwort schlechtes Training war (blankes 'except'). – vaultah

1

Wenn Sie einen Artikel brauchen und wollen nicht unbedingt Pop, Sie next mit Ihrem vorhandenen Generator Ausdruck verwenden können:

result = next(x for x in l if x.attr1 == 'T2') 
1

Wenn es erlaubt ist, das Ergebnis als Array zu erhalten:

result = filter(lambda x: x.attr1 == 'T2', l) 

Oder wenn Sie nur wollen, um eins zu bekommen, dann:

result = filter(lambda x: x.attr1 == 'T2', l).pop() 
Verwandte Themen