2017-05-31 1 views
11

Disons que j'ai trois listes et j'ai besoin de itérer à travers eux et faire des choses au contenu. Les trois listes sont les suivantes: streaks_0, streaks_1 et streaks_2. Pour chaque liste, j'ai besoin d'utiliser différentes valeurs spécifiques à chaque liste. Par exemple, streak_0_num0s ne fonctionnera pas dans la boucle streaks_1.Python, je me répète beaucoup quand il s'agit de boucles for et il doit y avoir une meilleure façon

Existe-t-il un moyen de transformer ces trois boucles en une seule ou au moins une façon de nettoyer cela?

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

bien sûr: utiliser une liste de dictionnaires par exemple. Mais ce serait mieux adapté pour http://codereview.stackexchange.com –

+10

Je vote pour fermer cette question hors-sujet parce que http://codereview.stackexchange.com/ est le site pour demander des améliorations de code –

+2

Sans rapport à votre question: réduisez "elif number! = 0" à un simple "else". – jarmod

Répondre

14

Pourquoi ne pas utiliser une fonction?

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

Un petit problème, mais sûrement votre fonction comme écrite doit être nommée 'print_average' au lieu de' get_average', car il imprime le résultat au lieu de le retourner? Bien sûr, avoir une fonction imprimer automatiquement son résultat est généralement une odeur de code de toute façon ... –

+1

@IlmariKaronen Ou mieux encore, avoir 'get_average' retourne effectivement la valeur et place le' print' en dehors de celui-ci. – jpmc26

+0

@IlmariKaronen très vrai, j'ai fondamentalement pris son code comme écrit et fait un exemple rapide. Mais oui, il devrait vraiment dire print_average, ou comme jpmc26 l'a souligné, retourner les résultats et ensuite faire quelque chose avec – CodeLikeBeaker

11

Votre code peut facilement être simplifié avec une fonction comme ci-dessous un:

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

ou celui-ci si vous préférez:

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

et voici un petit exemple d'utilisation:

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

Écrire une fonction ion, que vous pouvez appeler plusieurs fois:

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

Comme les autres déjà dit: Lorsque vous vous trouvez-vous répéter beaucoup de fois: essayez de créer une fonction qui peut être réutilisée.

Cependant, c'est toujours une bonne idée de jeter un coup d'œil et de voir si quelqu'un a déjà implémenté une telle fonction. Dans votre cas, vous pouvez utiliser numpy.mean (numpy est un module tiers) ou statistics.mean (statistics est un module intégré dans python 3.4+).

La seule chose qu'ils ne le font pas par défaut est l'exclusion des zéros, donc vous devez faire vous-même:

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 

ou:

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