2016-03-16 34 views
6

Zmienna a może przyjmować dowolną liczbę wartości. Wartość a jest ilością dodatkowych predefiniowanych warunków, które należy spełnić dla pętli while.Masz dodatkowe warunki pętli ... na podstawie warunku?

Można tego dokonać za pomocą wielu instrukcji elif, ale czy istnieje lepszy sposób na wykonanie tego?

if a == 0: 
    while condition_1: 
     ... 
elif a == 1: 
    while condition_1 or condition_2: 
     ... 
elif a == 2: 
    while condition_1 or condition_2 or condition_3: 
     ... 
+0

Co próbujesz osiągnąć? Czy mógłbyś podać nam bardziej konkretny przykład? – Bahrom

Odpowiedz

10

Ogólny sposób robi to, co robić inne języki z switch oświadczenie jest stworzenie słownika zawierającego funkcję dla każdego z przypadków:

conds = { 
    0: lambda: condition_1, 
    1: lambda: condition_1 or condition_2, 
    2: lambda: condition_1 or condition_2 or condition_3 
} 

wówczas:

while conds[a](): 
    # do stuff 

Korzystając lambdy (lub nazwane funkcje, jeśli twoje warunki są szczególnie złożone) odpowiedni stan może być oceniany za każdym razem w pętli, zamiast raz, gdy zdefiniowany jest słownik.

W tym prostym przypadku, gdy twoje a ma sekwencyjne liczby całkowite zaczynające się od 0, możesz użyć listy i zapisać trochę pisania. Aby jeszcze bardziej uprościć, można określić każdego ze swoich warunków w odniesieniu do poprzedniego, ponieważ jesteś po prostu dodając warunek za każdym razem:

conds = [ 
    lambda: condition_1, 
    lambda: conds[0]() or condition_2, 
    lambda: conds[1]() or condition_3 
] 

Albo, jak sugeruje Julien w komentarzu:

conds = [ 
    lambda: condition_1, 
    lambda: condition_2, 
    lambda: condition_3 
] 

while any(cond() for cond in conds[:a+1]): 
    # do stuff 
+2

+1 za sprytne i uproszczone rozwiązanie. Możesz jednak określić, dlaczego lambdas - jeśli poprawnie interpretuję, to dlatego, że nie używanie ich spowoduje, że wartości boolowskie zostaną ustalone przy inicjalizacji słownika, prawda? – BHustus

+1

Tak. Można również użyć nazwanych funkcji dla szczególnie złożonych warunków. W każdym przypadku musi to być funkcja odroczenia oceny do później (i umożliwienia powtórnej oceny). – kindall

+1

Osobiście polecam umieszczenie tego bezpośrednio w odpowiedzi, więc jeśli ktoś, kto nie zrozumie, otrzyma natychmiastowe wyjaśnienie. – BHustus

3

Czy próbowałeś coś takiego:

while (a >= 0 and condition_1) or (a >= 1 and condition_2) or (a >= 2 and condition_3) ... 
+2

Chociaż technicznie poprawne, chciałbym doradzić czytelnikom, że jest to rozwiązanie nieco rozwlekłe, przesadne i nie-Pythoniczne, zwłaszcza jeśli warunki warunkowe stają się coraz bardziej złożone. – BHustus

+0

Trochę mniej elegancka odpowiedź była dla mnie odpowiednia. Czy możesz mi wyjaśnić, jak to działa? jest '(a> = 0 and condition_1)' instrukcja mini-if? – Lobstw

+0

Słowo kluczowe 'and' jest logicznym odpowiednikiem zagnieżdżonych instrukcji' if', więc sortuj ... – kindall

2

Można zdefiniować funkcję być oceniane za while:

def test(a): 
    if a == 1: 
     return condition1(...) 
    elif a == 2: 
     return condition2(...) or condition1(...) 
    elif a == 3: 
     return condition2(...) or condition1(...) or condition3(...) 
    else: 
     return False 

# test(a) will check the conditions ... define additional arguments if you need them 
while test(a): 
    do_stuff 

To ma nadal elifs ale nie trzeba wielokrotnie pisząc while.