2017-05-31 37 views
11

可以說我有三個列表,我需要遍歷它們並做一些內容。Python,我在重複自己很多,當涉及到循環,並且必須有更好的方式

這三個列表是streaks_0,streaks_1streaks_2。對於每個列表,我需要使用特定於每個列表的不同值。例如,streak_0_num0sstreaks_1 for循環中將不起作用。

有沒有辦法讓這三個循環成爲一個或至少一個方法來清理呢?

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

:使用字典的名單例如。但是,這將是最適合http://codereview.stackexchange.com –

+10

我投票結束這個問題作爲脫離主題,因爲http://codereview.stackexchange.com/是要求代碼改進的網站 –

+2

不相關到你的問題:減少「elif number!= 0」爲一個簡單的「其他」。 – jarmod

回答

14

爲什麼不使用函數?

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

一個小問題,但是你寫的函數當然應該命名爲'print_average'而不是'get_average',因爲它打印結果而不是返回它?當然,有一個函數自動打印其結果通常是一個代碼的氣味...... –

+1

@IlmariKaronen或者更好的是,讓'get_average'實際返回值並將'print'放在它外面。 – jpmc26

+0

@IlmariKaronen非常真實,我基本上把他的代碼寫成了一個簡單的例子。但是,是的,它應該說print_average,或者jpmc26指出,返回結果,然後做一些事情 – CodeLikeBeaker

11

您的代碼可以與下面的一個類似的功能很容易簡化爲:

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

或這一個,如果你喜歡:

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

,這裏是一個小的使用例子:

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

寫一個函數離子,就可以多次調用:

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

正如別人已經說過:當你發現你自己重複了很多遍:嘗試創建可重複使用的功能。

但是,環顧一下並查看是否有人已經實現了這樣的功能總是一個好主意。在你的情況下,你可以使用numpy.meannumpy是第三方模塊)或statistics.meanstatistics是python 3.4+中的內置模塊)。

他們不默認做的是不包括零,所以你必須自己做的唯一的事情:

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 

或:

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 
當然
相關問題