2012-12-25 9 views
60

Przeczytałem poniższe linki, ale to nie odpowiada na moje pytanie.
Does Python have a ternary conditional operator? (pytanie jest o kondensacyjny if-else do jednej linii)
Umieszczenie instrukcji if-elif-else w jednej linii?

Czy istnieje prostszy sposób pisania instrukcję if-elif-else tak, że pasuje na jednej linii?
Na przykład

if expression1: 
    statement1 
elif expression2: 
    statement2 
else: 
    statement3 

[UPDATE]

if i>100: 
    x=2 
elif i<100: 
    x=1 
else: 
    x=0 

prostu czuję, jeśli powyższy przykład można zapisać w następujący sposób, mogłoby to wyglądać bardziej zwięzłe.

x=2 if i>100 elif i<100 1 else 0 [WRONG] 

Odpowiedz

91

Nie, nie jest to możliwe (przynajmniej nie w przypadku stwierdzeń arbitralnych), ani nie jest pożądane. Dopasowanie wszystkiego do jednej linii najprawdopodobniej naruszyłoby PEP-8, gdzie nakazuje się, aby linie nie przekraczały 80 znaków.

To także przeciwko Zenowi Pythona: "Czytelność się liczy". (Wpisz import this w zachęcie Python, aby przeczytać całość).

Ty może używać potrójny wyraz w Pythonie, ale jedynie do wyrażenia, a nie stwierdzeń:

>>> a = "Hello" if foo() else "Goodbye" 

Edit:

zmienione pytanie teraz pokazuje, że trzy stwierdzenia są identyczne z wyjątkiem przypisanej wartości. W tym przypadku, przykuty operator trójargumentowy działa, ale nadal uważam, że jest to mniej czytelny:

>>> i=100 
>>> a = 1 if i<100 else 2 if i>100 else 0 
>>> a 
0 
>>> i=101 
>>> a = 1 if i<100 else 2 if i>100 else 0 
>>> a 
2 
>>> i=99 
>>> a = 1 if i<100 else 2 if i>100 else 0 
>>> a 
1 
+0

Dlaczego drugie wyrażenie nie zwróciło 0? _i_ jest powyżej 100 – AstralWolf

+1

@AstralWolf: Tak, a wyrażenie mówi: "2 jeśli i> 100" ... –

+0

Hmm, przeczytaj to jako "jeśli i> 100 jeszcze 0" nieumyślnie to teraz pobierz – AstralWolf

36

Jeśli potrzebujesz tylko różne wyrażenia dla różnych przypadkach to może pracować dla Ciebie:

expr1 if condition1 else expr2 if condition2 else expr 

Na przykład:

a = "neg" if b<0 else "pos" if b>0 else "zero" 
+1

'" pos "' to * nie * stwierdzenie, to wyrażenie. –

+0

@TimPietzcker Dzięki, zaktualizowałem post, aby był dokładniejszy. – Lycha

11

Po prostu zagnieżdż następną klauzulę if w instrukcji else. Ale to nie sprawia, że ​​wygląda ładniej.

>>> x=5 
>>> x if x>0 else ("zero" if x==0 else "invalid value") 
5 
>>> x = 0 
>>> x if x>0 else ("zero" if x==0 else "invalid value") 
'zero' 
>>> x = -1 
>>> x if x>0 else ("zero" if x==0 else "invalid value") 
'invalid value' 
2

To zależy również od natury twoich wyrażeń. Ogólna rada dotycząca innych odpowiedzi "nie robienia tego" jest całkiem słuszna w przypadku ogólnych stwierdzeń i ogólnych wyrażeń.

Ale jeśli potrzebujesz tylko tabeli "dispacth", np. Wywołującej inną funkcję w zależności od wartości danej opcji, możesz wywołać funkcje w słowniku.

Coś jak:

def save(): 
    ... 
def edit(): 
    ... 
options = {"save": save, "edit": edit, "remove": lambda : "Not Implemented"} 

option = get_input() 
result = options[option]() 

(że zamiast

if option=="save": 
    save() 
... 

)

1

Ludzie już wymienione wyrażenia potrójne. Czasami przy prostym przyporządkowaniu warunkowym jako przykładzie można użyć wyrażeń matematycznych do wykonania warunkowego przypisania. To może nie sprawić, że twój kod będzie czytelny, ale dostanie go na jednej dość krótkiej linii. Twój przykład można zapisać tak:

x = 2*(i>100) | 1*(i<100) 

Porównania byłoby Prawda czy fałsz, a kiedy pomnożenie numerami byłby wtedy albo 1 lub 0. Można by użyć + zamiast an | pośrodku.

2

Dobrze, natknąłem podobnymi problemami miesięcy temu wtedy pewnego dnia uświadomiłem sobie, że możesz faktycznie skorzystać z metody get obiektu obiektu .

x = {i>100: 2, i<100: 1}.get(True, 0) 

Zasadniczo i>100 i i<100 nie mogą być jednocześnie prawdziwe, więc jeśli któryś z nich jest True uzyskać żądaną wartość (2 lub 1), jeżeli żaden z nich nie jest True, masz 0.

+0

haha ​​... to jest miły mały hack, podobało mi się;) – akki

Powiązane problemy