Python,当涉及到循环时,我重复了很多次,一定有更好的方法

Python, I'm repeating myself a lot when it comes to for loops and there must be a better way

假设我有三个列表,我需要遍历它们并对内容做一些处理。

三个列表分别是streaks_0streaks_1streaks_2。对于每个列表,我需要使用特定于每个列表的不同值。例如,streak_0_num0sstreaks_1 for 循环中将不起作用。

有没有办法将这三个 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))

为什么不用函数?

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)

您的代码可以使用如下函数轻松简化:

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)))

写一个可以多次调用的函数:

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)

正如其他人所说:当你发现自己重复了很多次时:尝试创建一个可以重复使用的函数。

不过,环顾四周看看是否有人已经实现了这样的功能总是一个好主意。在您的情况下,您可以使用 numpy.mean (numpy is a 3rd party module) or 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