zip 函数如何处理元组

7 投票
5 回答
46837 浏览
提问于 2025-04-16 15:54

我希望有人能帮我解决一个我卡住的问题。我有很多元组(超过500个),它们看起来像这样:

(2,1,3,6)  
(1,2,5,5)  
(3,0,1,6)  
(10,1,1,4)  
(0,3,3,0)  

我代码中的一部分是:

sum1 = (A,B,C,D) # creates a tuple of sums of (A,B,C,D)  
mysum = map(sum, zip(A, B, C, D))
print(mysum)

我意识到上面的代码是不正确的。我想找到一种方法,使用zip函数把所有的A值加在一起,所有的B值加在一起,所有的C值加在一起,以及所有的D值加在一起。例如,我想打印出类似这样的内容:

Asum = 16  
Bsum = 7  
Csum = 13  
Dsum = 21  

有人能帮我吗?非常感谢你的时间。

5 个回答

2

如果你的数据集合大小都一样,并且你在使用C Python,建议你考虑使用numpy库。你可以这样在numpy中操作:

In [5]: sets = ((2,1,3,6),
   ...:         (1,2,5,5),
   ...:         (3,0,1,6),
   ...:         (10,1,1,4),
   ...:         (0,3,3,0)  )*100

In [6]: import numpy as np

In [7]: A = np.array(sets)

In [8]: np.sum(A, axis=0)
Out[8]: array([1600,  700, 1300, 2100])

numpy会把你的数值转换成一个数组,并且利用优化过的LAPACK函数高效地进行计算。

为了比较性能,我在两种假设下进行了测试。第一种假设是你的数据存储方式让导入到numpy数组中变得高效,所以我没有计算把集合转换成数组所需的时间。我比较了np.sum和[sum(x) for x in zip(*sets)]的性能。以下是每种情况的时间测试结果:

Excluding numpy Array Conversion: 0.0735958760122
Including numpy Array Conversion: 17.1435046214
Plain old zip: 0.660146750495

结论是,如果你的输入数据可以轻松导入到numpy中,那么使用numpy会更快。

4
map(sum, zip(a, b, c, d, e))

第一次调用 zip 的时候,它把列表的顺序反转了——也就是说,它把所有的第一个元素放在一起,所有的第二个元素放在一起,依此类推。

第二次调用 map,它把第一个参数 sum 应用到第二个参数,也就是那些列表上,最后返回一个包含 sum 结果的列表——这些结果实际上就是各个列表的总和。

16
>>> zip((1,2,3),(10,20,30),(100,200,300))
[(1, 10, 100), (2, 20, 200), (3, 30, 300)]

>>> [sum(x) for x in zip((1,2,3),(10,20,30),(100,200,300))]
[111, 222, 333]

要处理一组任意大小的元组,可以这样做:

>>> myTuples = [(1,2,3), (10,20,30), (100,200,300)]
>>> [sum(x) for x in zip(*myTuples)]
[111, 222, 333]

小提示:在Python 3中,zip函数返回的是一个懒惰的可迭代对象,你可以像处理其他可迭代对象一样,随时将它转换成列表:list(zip(...))

(感谢Seganku指出示例中的错误,这个修改被其他编辑拒绝了三次)

撰写回答