2012-11-27 11 views
12

Mam ten mały fragment kodu Pythona, który napisałem. Działa, ale myślę, że powinna istnieć bardziej usprawniona metoda osiągnięcia tych samych rezultatów. Po prostu tego nie widzę. Jakieś pomysły?Czy istnieje lepszy sposób napisania tej "jeśli" oceny Boolean?

if tx_avt >= 100: tx = 1 
elif tx_avt < 100 and tx_avt >= 50: tx = 2 
elif tx_avt < 50 and tx_avt >= 25: tx = 3 
elif tx_avt < 25 and tx_avt >= 12.5: tx = 4 
else: tx = 5 
+5

Byłoby to bardziej czytelne, gdyby umieścić przypisanie we własnym wierszu odpowiednio wcięte. –

Odpowiedz

29

można go zmienić na:

if tx_avt >= 100: tx = 1 
elif tx_avt >= 50: tx = 2 
elif tx_avt >= 25: tx = 3 
elif tx_avt >= 12.5: tx = 4 
else: tx = 5 

Objaśnienie:

  • Jeśli if tx_avt >= 100 nie jest prawdziwe, to można wywnioskować, że tx_avt < 100musi być prawdziwe.
  • Eliminuje to konieczność wykonywania części "tx_avt < 100" w czeku "elif tx_avt < 100 and tx_avt >= 50:".

sama logika kaskadami w dół & dotyczy reszty elif przypadkach.


Powiązane czytanie: Why Python Doesn't Have a Switch Statement, and its Alternatives.

+2

najbardziej kompletna odpowiedź do tej pory! – heltonbiker

+0

Ach, oczywiście! Teraz jest dla mnie oczywiste! z jakiegoś powodu miałem to w głowie, muszę ocenić między liczbą z instrukcją AND. Dziękuję za wyjaśnienie.Idealnie byłoby użyć instrukcji switch/case, jeśli używałem C++. Znacznie czystsze. Tak to idzie. Sprawdzę link. – DavidScott612

10

nie trzeba górne granice dotyczące elifs ponieważ są one rozstrzygane przez klauzuli nad nimi ...

elif tx_avt >= 50 : #do something 
elif tx_avt >= 25 : #somthing else 

na marginesie w Pythonie można zrobić

if 3 < ab < 10 : #check if ab is between 3 and 10 
+0

Kontrola interwałów jest interresting! Czy wiesz, gdzie można go znaleźć w odnośniku do języka? Chciałbym zobaczyć, jak ewaluacja działa dla innych typów niż liczby całkowite –

+2

jest trochę w pierwszym akapicie tutaj http://docs.python.org/2/reference/expressions.html#not-in –

+0

Ah, który jest ciekawy smakołyk Nie wiedziałem o Pyhton. dzięki! – DavidScott612

8

Jeśli urządzenie if-elif-else łańcuch robi się naprawdę długo można korzystać z tej metody:

for amt, tx in [(100, 1), (50, 2), (25, 3), (12.5, 4)]: 
    if tx_avt >= amt: 
     break 
else: 
    tx = 5 

note: Klauzula else pętli for jest wykonywana, gdy nie napotkano break. W tym przypadku służy do zapewnienia domyślnego przypadku.

+0

Twoja notatka jest nieco błędna ... reszta jest wykonywana, jeśli nie jesteś w bloku if lub elif po wyjściu z pętli ... –

+1

@JoranBeasley: Niepoprawnie. Zobacz dokumentację w języku Python [4.4. instrukcje 'break' i' continue' oraz 'else' Clauses on Loops] (http://docs.python.org/2/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses- on-loops): "Polecenia pętli mogą mieć klauzulę" else ", wykonywane są, gdy pętla kończy się wyczerpaniem listy (z' for') lub gdy warunek staje się fałszywy (z 'while'), ale nie kiedy pętla jest zakończona przez instrukcję 'break'." –

+0

oh fajne dzięki :) ... Myślałem, że zostały wykonane inaczej, ale dobrze wiedzieć –

3

Aby dać inny pomysł, można to zrobić w jednym liniowcu za pomocą funkcji wyszukiwania binarnego w module bisect.

In [106]: def index(a,x): 
    .....:   return len(a) - bisect.bisect_right(a, x) + 1 
    .....: 

In [107]: a=[12.5,25,50,100] 

In [108]: index(a,15) 
Out[108]: 4 

In [109]: index(a,25) 
Out[109]: 3 

In [110]: index(a,35) 
Out[110]: 3 

In [111]: index(a,50) 
Out[111]: 2 

In [112]: index(a,100) 
Out[112]: 1 
+2

+1. Nie zapomnij poradzić sobie z domyślnym przypadkiem. –

0

Jeszcze inny pomysł opiera się na fakcie, że [12,5, 25, 50, 100] to seria:

MAX_BOUNDARY = 5 
for tx, boundary in [(n, 25 * 2**(-n+3)) for n in range(1, MAX_BOUNDARY)]: 
    if tx_avt >= boundary: 
     break 
else: 
    tx = MAX_BOUNDARY 

(to nieco zmodyfikowana wersja @StevenRumbalski)

ten mógł być połączonym z ideą @WaiYipTung o numerze bisect dla zapytania O (log (n)), jeśli dystrybucja tx_avt jest jednolita (funkcja serii w) i twoja lista staje się BARDZO duża.

W przeciwnym razie należy trzymać się prostsze i łatwiejsze do zrozumienia i rozwiązania jak @JoranBeasley @SampsonChen sugerowane.

Powiązane problemy