`elif` in Listenverständnisbedingungen

128

Können wir elifbeim Listenverständnis verwenden?

Beispiel:

l = [1, 2, 3, 4, 5]

for values in l:
    if values==1:
        print 'yes'
    elif values==2:
        print 'no'
    else:
        print 'idle'

Können wir das elifin unser Listenverständnis aufnehmen, ähnlich wie im obigen Code?

Zum Beispiel eine Antwort wie:

['yes', 'no', 'idle', 'idle', 'idle']

Bisher habe ich nur ifund elseim Listenverständnis verwendet.

selbst
quelle

Antworten:

249

Pythons bedingte Ausdrücke wurden genau für diese Art von Anwendungsfall entwickelt:

>>> l = [1, 2, 3, 4, 5]
>>> ['yes' if v == 1 else 'no' if v == 2 else 'idle' for v in l]
['yes', 'no', 'idle', 'idle', 'idle']

Hoffe das hilft :-)

Raymond Hettinger
quelle
5
Die Syntax enthält eine interessante Geschichte. Viele Jahre vor ihrer Einführung waren "tertiäre Ausdrücke" eine der fünf am häufigsten nachgefragten Änderungen in der Sprache. Da Guido van Rossum es ausdrücklich als eine auf Aussagen basierende Sprache entwarf, widersetzte er sich lange Zeit entschieden (tertiäre Ausdrücke und insbesondere deren Missbrauch sind Quellen von viel Dunkelheit im Code). Als er schließlich erlag, gab er bekannt, dass er absichtlich eine Syntax gewählt hatte, die von Überbeanspruchung abhielt. Trotzdem hat er wie immer einen eleganten Designjob gemacht.
Holdenweb
1
Ternär, verdammt (schrieb er und bemerkte seinen Legastheniefehler zu spät, um ihn zu bearbeiten).
Holdenweb
2
Während ich diese Antwort abstimme, möchte ich Folgendes erwähnen: Für 1 Paar, wenn / sonst leicht zu lesen ist, 2 Paare: Es wird schwieriger zu verstehen. Erwähne nicht einmal 3 Paare. Wenn der Ausdruck 3 oder mehr Paare benötigt, erleichtert ein Wörterbuch oder eine separate Funktion das Lesen und Verstehen.
Hai Vu
1
Ich möchte keine Lösung für dieses Problem hinzufügen, sondern eine Erinnerung an sauberen Code: Da dieses Listenverständnis drei Bedingungen hat, könnte es wahrscheinlich in eine beschreibendere Methode umgestaltet werden. Mein Punkt ist dieser: martinfowler.com/bliki/FunctionLength.html :)
Alvaro Cavalcanti
Ich bin auf einen Fall gestoßen, in dem ich einen Elif brauchte, aber nur zwei Werte. Mit diesem Beispiel hätte ich nur ['yes', 'no']gemacht werden müssen. Dazu können Sie Folgendes tun : ['yes' if v == 1 else 'no' for v in l if values in [1,2]]. Ich kann mir derzeit keinen saubereren Weg vorstellen, dies zu tun.
dTanMan
48
>>> d = {1: 'yes', 2: 'no'}
>>> [d.get(x, 'idle') for x in l]
['yes', 'no', 'idle', 'idle', 'idle']
Ignacio Vazquez-Abrams
quelle
4
Ich denke, diese Form ist viel einfacher zu verdauen, als zu versuchen, eine wirklich lange und komplizierte if / else-Logik innerhalb der Liste zu
erstellen
5
@jdi Obwohl bedingte Ausdrücke können nicht nach Ihrem Geschmack sein, sie wurden speziell auf Griff entworfen if-elif-elif-else - Ketten, wie der OP angefordert. Sie sind nicht schwer zu erlernen und können Situationen angemessen bewältigen, die für die Wörterbuch-Suchlogik nicht so geeignet sind : 'A' if grade>=90 else 'B' if grade>=80 else 'C' if grade>=70 else 'F'.
Raymond Hettinger
1
Gibt es einen Vorteil, daußerhalb des Verständnisses zu definieren?
Chris_Rands
Der Grund, warum mir das Listenverständnis besser gefällt, ist, dass es genau wie Englisch liest. Selbst ein Nicht-Programmierer könnte verstehen, was er tut. Mit dieser Lösung müssen Sie die dict.get () -Methode verstehen.
Tim Skov Jacobsen
25

Sie können irgendwie.

Beachten Sie Folgendes, wenn Sie Sytax verwenden:

['yes' if v == 1 else 'no' for v in l]

Sie verwenden die ternäre Form des if / else-Operators (wenn Sie mit Sprachen wie C vertraut sind, entspricht dies dem ?:Konstrukt :) (v == 1 ? 'yes' : 'no').

In der ternären Form des if / else-Operators ist kein 'elif' integriert, aber Sie können es im 'else'-Zustand simulieren:

['yes' if v == 1 else 'no' if v == 2 else 'idle' for v in l]

Das ist wie zu sagen:

for v in l:
    if v == 1 :
        print 'yes'
    else:
        if v == 2:
            print 'no'
        else:
            print 'idle'

Es gibt also kein direktes 'elif'-Konstrukt, nach dem Sie gefragt haben, aber es kann mit verschachtelten if / else-Anweisungen simuliert werden.

mathematisch.Kaffee
quelle
Der letzte Absatzcode ist sehr aufschlussreich, danke!
Devianceee
3

Vielleicht willst du das:

l = [1, 2, 3, 4, 5] 

print ([['idle','no','yes'][2*(n==1)+(n==2)] for n in l])
Ratnesh Kushwaha
quelle
2

Sie können das Listenverständnis verwenden, wenn Sie eine andere Liste aus dem Original erstellen.

>>> l = [1, 2, 3, 4, 5]
>>> result_map = {1: 'yes', 2: 'no'}
>>> [result_map[x] if x in result_map else 'idle' for x in l]
['yes', 'no', 'idle', 'idle', 'idle']
San4ez
quelle
2

Eine andere einfache Möglichkeit besteht darin, das bedingte Listenverständnis wie folgt zu verwenden:

l=[1,2,3,4,5]
print [[["no","yes"][v==1],"idle"][v!=1 and v!=2] for v in l]

gibt Ihnen die richtige Antwort:

['Ja', 'Nein', 'Leerlauf', 'Leerlauf', 'Leerlauf']

Stefan Gruenwald
quelle