如何对任意数量的迭代器使用zip实现类似hstack的合并?
如何对任意数量的迭代器使用zip实现类似hstack的合并?
嗨,这个场景我太熟悉了!固定数量的列表好处理,但当字典里的键/列表数量不确定时,核心就在于用解包操作把所有迭代器传给zip,而不是把它们当成单个元素传入。
先直接给你最简洁的解决方案,完全不用导入任何模块:
data = {'2015': [2, 1, 4, 3, 2, 4], '2016': [5, 3, 3, 2, 4, 6], '2017': [3, 2, 4, 4, 5, 3]} # 核心是用*解包字典的所有值作为zip的多个参数 hstack_tuple = sum(zip(*data.values()), ()) print(hstack_tuple) # 输出: (2, 5, 3, 1, 3, 2, 4, 3, 4, 3, 2, 4, 2, 4, 5, 4, 6, 3)
为什么这个方法有效?
data.values()直接拿到字典里所有的列表,比遍历keys再取值要简洁得多。*data.values()是Python的解包操作,它会把每个列表作为独立参数传给zip——这和你手动写zip(data['2015'], data['2016'], data['2017'])的效果完全一致!- 后续的
sum(..., ())就是把zip返回的一个个小元组(比如(2,5,3)、(1,3,2))拼接成一个大元组,和你最初处理固定列表的逻辑完全匹配。
你之前的尝试为什么不对?
你写的zip(data[val] for val in data.keys()),其实是把每个完整列表作为生成器的一个元素传给zip,zip会把这些列表当成独立的“列”,最终得到的是包含三个原列表的元组,这显然不是你要的按位置合并的效果。而解包操作正好解决了这个问题,让zip能正确按位置配对每个列表的元素。
如果你想要列表而不是元组
可以用列表推导式,可读性可能更好:
hstack_list = [item for group in zip(*data.values()) for item in group] print(hstack_list) # 输出: [2, 5, 3, 1, 3, 2, 4, 3, 4, 3, 2, 4, 2, 4, 5, 4, 6, 3]
这个推导式逻辑很直观:先遍历zip生成的每个分组元组,再把元组里的每个元素依次加入新列表,完全实现了你手动循环的效果,但代码简洁太多。
备注:内容来源于stack exchange,提问作者Zim
相关产品推荐
相关产品推荐

