if else in a list comprehension [duplicate]

To pytanie ma już odpowiedź tutaj:

Mam listę l:

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

Dla liczb powyżej 45 włącznie, chciałbym dodać 1; A dla liczb mniejszych od niego, 5.

Próbowałem

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

Ale to daje mi błąd składni. Jak mogę osiągnąć ifelse w ten sposób na liście?

Author: Keith Pinson, 2010-12-10

8 answers

>>> 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]

Zrób coś Jeśli <condition>, Zrób coś innego.

 349
Author: user225312,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-17 20:33:41

Powód, dla którego otrzymujesz ten błąd, ma związek z tym, jak wykonuje się zrozumienie listy.

Należy pamiętać, co następuje:

[ expression for item in list if conditional ]

Jest równoważne:

for item in list:
    if conditional:
        expression

Gdzie {[4] } jest w nieco innym formacie(pomyśl o zmianie kolejności podmiotu i czasownika w zdaniu).

Dlatego Twój kod [x+1 for x in l if x >= 45] robi tak:

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

Jednak ten kod [x+1 if x >= 45 else x+5 for x in l] robi to (po przestawianiu expression):

for x in l:
    if x>=45: x+1
    else: x+5
 190
Author: arboc7,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-10 08:00:55
[x+1 if x >= 45 else x+5 for x in l]

A Dla nagrody oto komentarz, który napisałem, aby zapamiętać to za pierwszym razem, gdy zrobiłem ten błąd:

Wyrażenie warunkowe Pythona to a if C else b i nie może być użyte jako:

[a for i in items if C else b]

Właściwa forma to:

[a if C else b for i in items]

Mimo, że istnieje prawidłowa forma:

[a for i in items if C]

Ale to nie to samo co filtrowanie przez C, ale można je łączyć:

[a if tC else b for i in items if fC]
 138
Author: Dan D.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-03 18:55:08

Musisz umieścić wyrażenie na początku listy, a wyrażenie if na końcu filtruje elementy!

[x+1 if x >= 45 else x+5 for x in l]
 84
Author: AndiDog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-10 06:48:04

Można również umieścić wyrażenie warunkowe w nawiasach wewnątrz listy:

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

[false, true] [warunek] to składnia

 14
Author: Stefan Gruenwald,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-04 06:50:06

Właśnie miałem podobny problem i znalazłem to pytanie i odpowiedzi naprawdę przydatne. To jest ta część, o której byłem zdezorientowany. Piszę to wyraźnie, ponieważ nikt nie powiedział tego po prostu po angielsku:

iteracja idzie na końcu.

Normalnie, pętla idzie

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

Każdy podaje część rozumienia listy po prostu tak, jak pierwsza odpowiedź,

[ expression for item in list if conditional ] 
Ale w tym przypadku nie tak się robi. (Próbowałem to zrobić, że sposób)

W tym przypadku jest to bardziej tak:

[ expression if conditional else other thing for this many times ] 
 8
Author: szeitlin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-18 17:34:43

Jak w [a if condition1 else b for i in list1 if condition2], dwa if S z condition1 i condition2 robią dwie różne rzeczy. Część (a if condition1 else b) pochodzi z wyrażenia lambda:

lambda x: a if condition1 else b

Podczas gdy druga condition2 to inna lambda:

lambda x: condition2

Cała lista może być traktowana jako kombinacja map i filter:

map(lambda x: a if condition1 else b, filter(lambda x: condition2, list1))
 8
Author: Xiaojun Chen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-02 00:43:16

Możesz przenieść warunek do:

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

Ale zaczyna wyglądać trochę brzydko, więc może lepiej będzie użyć normalnej pętli. Zauważ, że użyłem v zamiast l dla zmiennej list, aby zmniejszyć zamieszanie z liczbą 1 (myślę, że l i O Należy unikać jako nazw zmiennych w każdych okolicznościach, nawet w przykładzie szybkiego i brudnego kodu).

 7
Author: Jeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-10 06:52:44