wake-up-neo.com

wenn sonst in einem Listenverständnis

Ich habe eine Liste l:

l = [22, 13, 45, 50, 98, 69, 43, 44, 1]

Für Zahlen über 45 einschließlich möchte ich 1 hinzufügen; und für Zahlen unter 5.

Ich habe es versucht

[x+1 for x in l if x >= 45 else x+5]

Aber es gibt mir einen Syntaxfehler. Wie kann ich in einem Listenverständnis eine if - else erreichen?

372
user225312
>>> l = [22, 13, 45, 50, 98, 69, 43, 44, 1]
>>> [x+1 if x >= 45 else x+5 for x in l]
[27, 18, 46, 51, 99, 70, 48, 49, 6]

Tun Sie etwas, wenn <condition>, sonst tun Sie etwas anderes.

420
user225312

Der Grund, warum Sie diesen Fehler erhalten, hängt damit zusammen, wie das Listenverständnis durchgeführt wird.

Beachten Sie Folgendes:

[ expression for item in list if conditional ]

Ist äquivalent zu:

for item in list:
    if conditional:
        expression

Wobei das expression ein etwas anderes Format hat (denken Sie daran, das Thema und die Verbreihenfolge in einem Satz zu wechseln).

Daher führt Ihr Code [x+1 for x in l if x >= 45] Folgendes aus:

for x in l:
    if x >= 45:
        x+1

Dieser Code [x+1 if x >= 45 else x+5 for x in l] erledigt dies jedoch (nach der Neuanordnung von expression):

for x in l:
    if x>=45: x+1
    else: x+5
221
arboc7
[x+1 if x >= 45 else x+5 for x in l]

Und als Belohnung hier der Kommentar, den ich geschrieben habe, um mich daran zu erinnern, als ich diesen Fehler zum ersten Mal gemacht habe:

Pythons bedingter Ausdruck ist a if C else b und kann nicht verwendet werden als:

[a for i in items if C else b]

Die richtige Form ist:

[a if C else b for i in items]

Obwohl es ein gültiges Formular gibt:

[a for i in items if C]

Aber das ist nicht dasselbe, wie Sie nach C filtern, aber sie können kombiniert werden:

[a if tC else b for i in items if fC]
189
Dan D.

Sie müssen den Ausdruck am Anfang des Listenverständnisses setzen, eine if-Anweisung am Ende filtert Elemente!

[x+1 if x >= 45 else x+5 for x in l]
96
AndiDog

Wie in [a if condition1 else b for i in list1 if condition2] machen die beiden ifs mit condition1 und condition2 zwei verschiedene Dinge. Der Teil (a if condition1 else b) stammt aus einem Lambda-Ausdruck:

lambda x: a if condition1 else b

während der andere condition2 ein anderer Lambda ist:

lambda x: condition2

Das gesamte Listenverständnis kann als Kombination von map und filter betrachtet werden:

map(lambda x: a if condition1 else b, filter(lambda x: condition2, list1))
17
Xiaojun Chen

Sie können den bedingten Ausdruck auch in Klammern innerhalb des Listenverständnisses setzen:

    l = [22, 13, 45, 50, 98, 69, 43, 44, 1]
    print [[x+5,x+1][x >= 45] for x in l]

[false, true] [condition] ist die Syntax

16

Ich hatte gerade ein ähnliches Problem und fand diese Frage und die Antworten wirklich nützlich. Hier ist der Teil, über den ich verwirrt war. Ich schreibe es explizit, weil niemand es einfach auf Englisch gesagt hat:

Die Iteration endet.

Normalerweise geht eine Schleife

for this many times:
    if conditional: 
        do this thing
    else:
        do something else  

Jeder gibt den Listenverständnisteil einfach so an wie die erste Antwort,

[ expression for item in list if conditional ] 

aber das ist eigentlich nicht das, was Sie in diesem Fall tun. (Ich habe versucht, es so zu machen)

In diesem Fall ist es eher so:

[ expression if conditional else other thing for this many times ] 
9
szeitlin

Sie können die Bedingung verschieben auf:

v = [22, 13, 45, 50, 98, 69, 43, 44, 1]
[ (x+1 if x >=45 else x+5)  for x in v ]

Aber es fängt an, ein bisschen hässlich auszusehen, deshalb ist es vielleicht besser, eine normale Schleife zu verwenden. Beachten Sie, dass ich v anstelle von l für die Listenvariable verwendet habe, um Verwechslungen mit der Nummer 1 zu vermeiden (ich denke, l und O sollten unter keinen Umständen als Variablennamen verwendet werden , auch in schnell und schmutzig Beispielcode).

6
Jeet