2017-05-31 43 views
11

Powiedzmy, że mam trzy listy i potrzebuję ich powtórzyć i zrobić kilka rzeczy do zawartości.Python, powtarzam sobie dużo, jeśli chodzi o pętle i musi być lepszy sposób.

Trzy listy to: streaks_0, streaks_1 i streaks_2. Dla każdej listy muszę użyć różnych wartości charakterystycznych dla każdej listy. Na przykład streak_0_num0s nie będzie działać w pętli for streaks_1.

Czy istnieje sposób, aby te trzy pętle w jednym lub przynajmniej sposób to wyczyścić?

for number in streaks_0: 
    if number == 0: 
     streak_0_num0s += 1 
    elif number != 0: 
     streak_0_sum += number 
streak_0_average = (streak_0_sum/(len(streaks_0) - streak_0_num0s)) 

for number in streaks_1: 
    if number == 0: 
     streak_1_num0s += 1 
    elif number != 0: 
     streak_1_sum += number 
streak_1_average = (streak_1_sum/(len(streaks_1) - streak_1_num0s)) 

for number in streaks_2: 
    if number == 0: 
     streak_2_num0s += 1 
    elif number != 0: 
     streak_2_sum += number 
streak_2_average = (streak_2_sum/(len(streaks_2) - streak_2_num0s)) 
+1

przedmiotu: użycie listy słowników na przykład. Ale byłoby to najlepiej dostosowane do http://codereview.stackexchange.com –

+10

Głosuję, aby zamknąć to pytanie jako nie na temat, ponieważ http://codereview.stackexchange.com/ jest stroną, która prosi o ulepszenia kodu. –

+2

Niepowiązane na twoje pytanie: zmniejsz "elif number! = 0" do prostego "else". – jarmod

Odpowiedz

14

Dlaczego nie skorzystać z funkcji?

def get_average(streaks): 
    streak_0_num0s = 0 
    streak_0_sum = 0 

    for number in streaks: 
     if number == 0: 
      streak_0_num0s += 1 
     elif number != 0: 
      streak_0_sum += number 
    streak_0_average = (streak_0_sum/(len(streaks) - streak_0_num0s)) 
    print(streak_0_average) 

get_average(streaks01) 
get_average(streaks02) 
get_average(streaks03) 
+0

Niewielka wątpliwość, ale z pewnością twoja funkcja jako zapisana powinna być nazwana 'print_average' zamiast' get_average', ponieważ drukuje wynik zamiast zwracania go? Oczywiście funkcja automatycznego drukowania wyniku jest zwykle zapachem kodu ... Tak czy inaczej ... –

+1

@IlmariKaronen Albo jeszcze lepiej, czy 'get_average' zwraca wartość i umieszcza' print' poza nią. – jpmc26

+0

@IlmariKaronen bardzo prawdziwe, w zasadzie wziąłem jego kod jako napisany i wykonałem szybki przykład. Ale tak, to naprawdę powinieneś powiedzieć print_average, lub jak wskazano jpmc26, zwróć wyniki, a następnie zrób coś z nim – CodeLikeBeaker

11

Twój kod może być łatwo uprościć funkcję jak poniżej jednego:

def calculate_avg(lst): 
    return sum(lst)/(len(lst)-lst.count(0)) 

czy ten jeden, jeśli wolisz:

def calculate_avg(lst): 
    return sum(lst)/len([l for l in lst if l != 0]) 

i tu jest trochę przykładów użycia:

streaks = [ 
    [1, 2, 3, 0, 0, 0, 0], 
    [0, 0, 0, 4, 5, 6, 0], 
    [0, 0, 6, 7, 8, 0, 0] 
] 

for index, streak in enumerate(streaks): 
    print("avg(streak{})={}".format(str(index).zfill(2), calculate_avg(streak))) 
6

Napisz funkcję jonowy, który można wywołać wiele razy:

def calculate_average(values): 
    non_zeros = 0 
    sum = 0 

    for value in values: 
     if value != 0: 
      sum += value 
      non_zeros += 1 
    return sum/non_zeros 

streak_0_average = calculate_average(streaks_0) 
streak_1_average = calculate_average(streaks_1) 
streak_2_average = calculate_average(streaks_2) 
5

jak inni już powiedział: Kiedy znajdziesz powtarzasz sobie wiele razy: spróbuj utworzyć funkcję, które mogą być ponownie wykorzystane.

Jednak zawsze dobrze jest rozejrzeć się i zobaczyć, czy ktoś już wdrożył taką funkcję. W twoim przypadku możesz użyć numpy.mean (numpy to moduł zewnętrzny) lub statistics.mean (statistics jest wbudowanym modułem w pythonie 3.4+).

Jedyną rzeczą, której nie rób domyślnie jest bez zera, więc trzeba to zrobić samemu:

import numpy as np 

def average(streaks): 
    streaks = np.asarray(streaks) 
    streaks_without_zeros = streaks[streaks != 0] 
    return np.mean(streaks_without_zeros) 

streaks_0 = [1, 2, 3, 4, 0, 1, 2, 3] 
print(average(streaks_0)) # 2.2857142857142856 

czyli

import statistics 

def average(streaks): 
    streaks_without_zeros = [streak for streak in streaks if streak != 0] 
    return statistics.mean(streaks_without_zeros) 

streaks_0 = [1, 2, 3, 4, 0, 1, 2, 3] 
print(average(streaks_0)) # 2.2857142857142856