python - 通过组合相邻元素并削减元素的长度来转换元组列表

标签 python python-2.7

我有一个元组列表,长度为 x:

[(a1,a2,a3,a4),(b1,b2,b3,b4),(c1,c2,c3,c4),(d1,d2,d3,d4), ... ,(x1,x2,x3,x4)]  

我想创建一个新的元组列表如下:

[(a1,a2,b1,b2),(c1,c2,d1,d2),(e1,e2,f1,f2), ... ,((x-1)1,(x-1)2,x1,x2)]  

如您所见,子列表的所有第三个和第四个元素都消失了,并且相邻的子列表已合并。

我可以用几个循环来完成它,但我正在寻找优雅的 Python 风格的方式来完成它。

最佳答案

我思考了什么是 Pythonic 方式,得出的结论是如果您不需要序列,那么接受任何迭代器 将是 python 式的。 Martijn 的 xrange 方法在这个意义上并不是最 pythonic 的,而且确实是 Martijn 的石斑鱼方法

result = [ i[:2] + j[:2] for i, j in izip(*[iter(l)] * 2) ]    

是最 pythonic 的,因为它接受任何类型的可迭代对象。

[iter(l)] * 2 使用两个元素中的相同 迭代器生成一个 2 大小的列表。这比我对上面的 next 的尝试更快的原因是对 next() 的调用是昂贵的(所有函数调用相对于内联运算符的使用和元组的构造,CPython 上的属性/名称解析速度较慢)。


这是最简单明了的解决方案,我发现它是最符合 Pythonic 的,并且具有严格的列表:

l = [('a1', 'a2', 'a3', 'a4'), ('b1', 'b2', 'b3', 'b4'), ('c1', 'c2', 'c3', 'c4'), ('d1', 'd2', 'd3', 'd4')]
y = [ i[:2] + j[:2] for i, j in zip(l[::2], l[1::2]) ]
print y

打印

[('a1', 'a2', 'b1', 'b2'), ('c1', 'c2', 'd1', 'd2')]

但是它不是最有效的,因为 zip 和切片将在 Python 2 上创建临时列表,因此为了加快速度,可以使用 itertools.izip 使用 islice 生成生成解决方案。


但是,实际上可以在这里滥用迭代器来制作相当高效的代码,尽管不是很 Pythonic

i = iter(l)
n = i.next
result = [ j[:2] + n()[:2] for j in i ]
print result

打印

[('a1', 'a2', 'b1', 'b2'), ('c1', 'c2', 'd1', 'd2')]

列表理解中的for 隐式调用迭代器i 上的next() 并将结果赋值给j;在列表理解体中,我们显式推进相同的迭代器以获取下一个元组。然后通过元组切片,我们获取偶数元组(从 0 开始)的前 2 个元素,并将下一个元组的前 2 个元素连接到它。然而,如果原始列表中的元素数量不是偶数,此代码将导致 StopIteration 异常,这与 slice'n'zip 解决方案不同,后者只会默默地丢弃最后一个奇数元组。

关于python - 通过组合相邻元素并削减元素的长度来转换元组列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28591599/

相关文章:

python - 创建对标量求和的列

python - 使用 Mongomock 测试 $lookup 聚合

python-2.7 - GAE导入端点 "No module named endpoints"

python2.7 : matplotlib in jupyter notebook can't use qt

python-2.7 - Ansible 列表未排序

python - 如何使用 matplotlib 绘制这样的图

python - Matplotlib:annotate() 缺少 1 个必需的位置参数: 'self'

python - 我需要测试功能的哪些方面?

python - 没有声明编码

python - 快速生成 10,000 个随机整数元组