2012-10-12 14 views
9

Próbuję zrobić bardziej elegancką wersję tego kodu. To w zasadzie dołącza ciąg do kategorii number w zależności od liczby. Doceniam każdą pomoc.Jak zrobić elif statments bardziej elegancko, jeśli dodawanie do tablicy w pythonie

number = [100,150,200,500] 
categoryNumber = [] 

for i in range (0,len(number)): 
    if (number [i] >=1000): 
     categoryNumber.append('number > 1000') 
    elif (number [i] >=200): 
     categoryNumber.append('200 < number < 300') 
    elif (number [i] >=100): 
     categoryNumber.append('100 < number < 200') 
    elif (number [i] >=50): 
     categoryNumber.append('50 < number < 100')  
    elif (number [i] < 50): 
     categoryNumber.append('number < 50') 

for i in range(0,len(categoryNumber)): 
    print i 
+12

Ty nigdy ** ** chcą zrobić 'for i in range (0, len (liczba))' w Pythonie. To okropnie nietypowe. Po prostu zrób 'for i in number'. –

+0

Co jest nie tak z użyciem uczciwego "else:" dla tego ostatniego zdania? –

Odpowiedz

9

Jak o:

labels = (
    (1000, 'number >= 1000'), 
    (200, '200 <= number < 1000'), 
    (100, '100 <= number < 200'), 
    (50, '50 <= number < 100'), 
    (0, 'number < 50'), 
) 

for i in number: 
    for limit, label in labels: 
     if i >= limit: 
      categoryNumber.append(label) 
      break 
+2

Chociaż brakuje ci przypadku '<50'. Kod kategoryzacji zostałby umieszczony w oddzielnej funkcji dla zwiększenia czytelności. –

+0

@JeffMercado: Mogłem przysiąc, że tego nie było w oryginalnym pytaniu. :-P –

2

logiki wydaje się być dziwne, co chcesz zrobić na drugim Elif, ponieważ liczba [i] jest równa tarce wartości powyżej 200, np. 350, zostanie dodana kategoria "200 < numer < 300". Czy nie byłoby 200 < = numer < 1000?

+0

tak, twoje prawo było szybkie, np. powinno być 200 <= numer <1000 – user1741339

1

Osobiście jestem słabość do tego rodzaju rozwiązania:

number = [100,150,200,500] 

def getCategory(num): 
    return ['number < 50', '50 <= number < 100', '100 <= number < 200', '200 <= number < 1000', 'number >= 1000'][(num >= 50) + (num >= 100) + (num >= 200) + (num >= 1000)] 

categoryNumber = map(getCategory, number) 

Rozumiem, że czytelność cierpi trochę w funkcji. Korzystam również z faktu, że Python traktuje "Prawdziwy" jako 1. Łącząc kolejne porównania, znajduję właściwy wpis, aby powrócić.

Czyszczenie że się trochę, to jest ładniejszy patrzeć:

number = [100,150,200,500] 

def getCategory(num): 
    limits = [50, 100, 200, 1000] 
    msgList = ['number < 50', 
       '50 <= number < 100', 
       '100 <= number < 200', 
       '200 <= number < 1000', 
       'number >= 1000'] 
    return msgList[reduce(lamdba c, l: c+(num >= l), [0] + limits)] 

categoryNumber = map(getCategory, number) 

Co lubię o tym jest użycie „map” i „zredukować” zrobić pętle niepotrzebnych.

3

co powiesz na temat używania bisect?

>>> import bisect 
>>> categories = ['number < 50', '50 <= number < 100', '100 <= number < 200', '200 <= number < 300', '300 <= number <1000', 'number >= 1000'] 
>>> points = [50, 100, 200, 300, 1000] 
>>> categories[bisect.bisect(points, 1000)] 
'number >= 1000' 
>>> categories[bisect.bisect(points, 1)] 
'number < 50' 
>>> categories[bisect.bisect(points, 50)] 
'50 <= number < 100' 
+0

Myślę, że to najlepsze rozwiązanie ... –

1

coś takiego:

number = [199,75,235,1200,25,49,74,200,51,650] 
dic={(1000,float('inf')):'number > 1000', 
    (200,300):'200 < number < 300', 
    (100,200):'100 < number < 200', 
    (50,100): '50 < number < 100', 
    (0,50): 'number < 50'} 

for x in number: 
    for y in dic: 
    if x>y[0] and x<y[1]: 
     print(x,"is",dic[y]) 

wyjściowa:

199 is 100 < number < 200 
75 is 50 < number < 100 
235 is 200 < number < 300 
1200 is number > 1000 
25 is number < 50 
49 is number < 50 
74 is 50 < number < 100 
51 is 50 < number < 100 
+0

+1 za pomysł, -1 za nie czytanie pep8 – georg

+0

Co ze skrzynkami granicznymi? 200, 50, 1000? –

+0

@MartijnPieters Chyba zmienię warunek na 'if x> = y [0] i x = 200' –

0

Można uprościć rozwiązanie Martijn Pieters za. Zamiast tego kawałka proceduralnego kodu:

for i in number: 
    for limit, label in labels: 
     if i >= limit: 
      categoryNumber.append(label) 
      break 

Można użyć Quazi-funkcjonalny:

for number in numbers: 
    label = next(label for limit, label in labels if number >= limit) 
    categoryNumber.append(label) 
+0

+1: Podoba mi się to! –

0

Można użyć operator zrobić coś takiego:

import operator 
number = [101,151,201,500,1000,45] 
ops={operator.ge:'>=', operator.gt:'>',operator.lt:'<', operator.le:'<='} 
cats=(
    (1000, operator.ge,'number >= 1000'), 
    (200, operator.ge,'200 <= number < 1000'), 
    (100, operator.ge, '100 <= number < 200'), 
    (50, operator.ge, '50 <= number < 100'), 
    (50, operator.lt, 'number < 50')  
) 

for i in number: 
    for x, op, label in cats: 
     if op(i,x): 
      print '{0:5}{1:^4}{2:5} therefore: {3}'.format(i,ops[op],x,label) 
      break 

Drukuje:

101 >= 100 therefore: 100 <= number < 200 
    151 >= 100 therefore: 100 <= number < 200 
    201 >= 200 therefore: 200 <= number < 1000 
    500 >= 200 therefore: 200 <= number < 1000 
1000 >= 1000 therefore: number >= 1000 
    45 <  50 therefore: number < 50 

Albo można zrobić to this way:

for n in numbers: 
    result = next('{0:5}{1:^4}{2:5} therefore: {3}'.format(n,ops[op],x,label) 
         for limit, op, label in cats if op(n,limit)) 
    print result   
Powiązane problemy