Python, я много повторяю, когда речь заходит о циклах, и должен быть лучший способ
Давайте скажем, что у меня есть три списка, и мне нужно перебирать их и делать некоторые вещи для содержимого.
Три списка: streaks_0
, streaks_1
и streaks_2
. Для каждого списка мне нужно использовать разные значения, относящиеся к каждому списку. Например, streak_0_num0s
не будет работать в цикле streaks_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
Почему бы не использовать функцию?
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)
Ответ 2
Ваш код может быть легко упрощен с помощью функции, подобной приведенной ниже:
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)))
Ответ 3
Напишите функцию, которую вы можете вызывать несколько раз:
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)
Ответ 4
Как уже говорили другие: когда вы обнаружите, что вы повторяете себя много раз: попытайтесь создать функцию, которую можно повторно использовать.
Однако всегда полезно взглянуть и посмотреть, действительно ли кто-то уже реализовал такую функцию. В вашем случае вы можете использовать numpy.mean
(numpy
- сторонний модуль) или statistics.mean
(statistics
- встроенный модуль в 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