Python如何将列表相邻元素的平均值插入到原列表对应位置?
问题描述
给定原始列表:[1, 2, 4, 8, 16, 32]
期望得到的目标列表:[1, 2, 2, 3, 4, 6, 8, 12, 16, 24, 32]
转换规则如下:
- 最终列表需遵循
[原列表首元素, X, 原列表第二个元素, X, 原列表第三个元素, X, ..., 原列表尾元素]的交错结构 - 每个
X是原列表中相邻前后两个元素的四舍五入平均值 - 结果必须以原列表首元素开头、尾元素结尾
初始错误代码
最初写的代码只能生成所有相邻平均值组成的列表,直接覆盖了原列表内容,完全丢失了原列表元素,无法实现交错效果:
list_1 = [1, 2, 4, 8, 16, 32] list_1 = [round((list_1[i] + list_1[i+1])/2) for i in range(len(list_1)-1)] print(list_1)
运行输出为[2, 3, 6, 12, 24],不符合预期。
现有尝试方案
目前想到的思路是先生成平均值列表,再把两个列表合并后排序,代码如下:
list_1 = [1, 2, 4, 8, 16, 32] list_2 = [round((list_1[i] + list_1[i+1])/2) for i in range(len(list_1)-1)] list_1 = sorted(list_1 + list_2) print(list_1)
想确认是否存在更优的实现方式。
解答
你现在用的「生成平均值列表+合并排序」方案只在原列表严格单调的场景下能跑出正确结果,通用性很差:只要原列表不是单调递增/递减,排序操作就会打乱原元素的相对位置,得到的结果根本不符合交错排列的要求。比如拿非单调列表[1,5,3]测试,正确结果应该是[1,3,5,4,3],用排序方案会得到[1,3,3,4,5],完全错误。
更合理的实现是直接按交错规则构造结果,不需要排序,时间复杂度稳定在O(n),不受原列表顺序影响:
基础循环实现
逻辑非常直接:遍历原列表除最后一个元素外的所有项,每次先把当前原元素加入结果,再算它和下一个元素的平均值加进去,最后补上原列表的尾元素就行:
list_1 = [1, 2, 4, 8, 16, 32] res = [] for i in range(len(list_1) - 1): res.append(list_1[i]) res.append(round((list_1[i] + list_1[i+1]) / 2)) res.append(list_1[-1]) print(res) # 输出 [1, 2, 2, 3, 4, 6, 8, 12, 16, 24, 32]
精简写法
如果想写得更简洁,可以用zip配合嵌套推导式实现,不需要引入额外模块:
list_1 = [1, 2, 4, 8, 16, 32] res = [val for i in range(len(list_1)-1) for val in (list_1[i], round((list_1[i]+list_1[i+1])/2))] + [list_1[-1]]
处理超长列表时,也可以用itertools.chain优化内存占用:
from itertools import chain list_1 = [1, 2, 4, 8, 16, 32] avg_list = [round((a + b) / 2) for a, b in zip(list_1, list_1[1:])] res = list(chain.from_iterable(zip(list_1, avg_list))) + [list_1[-1]]
内容的提问来源于stack exchange,提问作者wildcat89
相关产品推荐
相关产品推荐

