Python嵌套列表同索引元素求和及平均值计算问题
问题描述
给定嵌套列表:
[ [0, 5, -3, 5, 0, 0], [-3, 0, 1, 0, 5, 0], [1, 0, 5, 0, -5, 0], [-3, 0, 3, 0, 0, 5]]
需要计算所有内列表中同索引元素的总和,排除0元素后计算平均值,结果存入新列表。例如:
- 索引0的元素求和:
0 + (-3) + 1 + (-3) = -5 - 非0元素数量为3,平均值:
-5/3 = -1.66666667
最终期望结果:
[ -1.66667, 5.0, 1.5, 5.0, 0.0, 5]
尝试的代码:
average_list = [] rating_values = [[0, 5, -3, 5, 0, 0], [-3, 0, 1, 0, 5, 0], [1, 0, 5, 0, -5, 0], [-3, 0, 3, 0, 0, 5]] for i in range(0, len(rating_values)): for j in range(0, len(rating_values[i])): total = 0 count = 0 if rating_values[i][j] != 0: total += rating_values[i][j] count += 1 average_rating = total / count if count > 0 else 0 average_list.append(average_rating)
得到错误结果:
[0, 5.0, -3.0, 5.0, 0, 0, -3.0, 0, 1.0, 0, 5.0, 0, 1.0, 0, 5.0, 0, -5.0, 0, -3.0, 0, 3.0, 0, 0, 5.0]
询问:如何在Python中仅遍历嵌套列表的同索引元素以实现需求?
解决方案
你的代码错误在于循环逻辑:外层遍历每个子列表,内层遍历子列表的每个元素,每次循环都重新初始化total和count,导致计算的是每个单独元素的“平均值”(要么是元素本身,要么是0),而非同索引所有元素的平均值。
正确的思路是先将同索引元素归为一组,再对每组计算总和与非0元素数量,最后求平均值。
方法1:使用zip转置列表
zip(*rating_values)可以将原嵌套列表转置,把每个索引对应的元素打包成一个元组,例如原列表索引0的元素会被打包成(0, -3, 1, -3)。
代码实现:
rating_values = [[0, 5, -3, 5, 0, 0], [-3, 0, 1, 0, 5, 0], [1, 0, 5, 0, -5, 0], [-3, 0, 3, 0, 0, 5]] average_list = [] # 遍历转置后的每个元素组 for elements in zip(*rating_values): # 筛选当前组的非0元素 non_zero = [num for num in elements if num != 0] if non_zero: # 计算平均值并保留5位小数 avg = round(sum(non_zero) / len(non_zero), 5) average_list.append(avg) else: average_list.append(0.0) print(average_list)
运行结果:
[-1.66667, 5.0, 1.5, 5.0, 0.0, 5.0]
方法2:按索引遍历(不使用zip)
如果不想用zip,可以先确定子列表的长度,然后遍历每个索引,收集所有子列表中该索引的元素:
rating_values = [[0, 5, -3, 5, 0, 0], [-3, 0, 1, 0, 5, 0], [1, 0, 5, 0, -5, 0], [-3, 0, 3, 0, 0, 5]] average_list = [] # 假设所有子列表长度一致,取第一个子列表的长度作为索引总数 index_count = len(rating_values[0]) for j in range(index_count): total = 0 count = 0 # 遍历每个子列表,取当前索引j的元素 for sub_list in rating_values: num = sub_list[j] if num != 0: total += num count += 1 # 计算平均值,无元素时返回0.0 avg = total / count if count > 0 else 0.0 average_list.append(round(avg, 5)) print(average_list)
运行结果与方法1一致。
关键说明
- 原代码的循环顺序错误:应该先遍历索引(外层循环为索引
j),再遍历每个子列表取该索引的元素;而非先遍历子列表,再遍历子列表内的元素。 - 计算平均值时,必须先收集同一索引的所有非0元素,再统一求和、计数,最后计算平均值。
内容的提问来源于stack exchange,提问作者JamieV
相关产品推荐
相关产品推荐

