在Python中将列表中的每一对元素收集到元组中

26
我有一个小整数列表,比如说:
[1, 2, 3, 4, 5, 6]

我希望收集连续的一对元素,并返回一个由这些元素对创建的新列表,即:

[(1, 2), (3, 4), (5, 6)]

我知道肯定有一种非常简单的方法来做到这一点,但是我无法理解。

谢谢


5
这是作业吗?如果是,请使用【作业】标签。 - S.Lott
2
可能是从单个列表中获取成对项等问题的重复。 - Jochen Ritzel
@S.Lott,为什么这可能是一项作业?从您的经验来看,它看起来像吗? - Senthil Kumaran
不重复:只是在快速搜索中找到的一些链接:https://dev59.com/62855IYBdhLWcg3wKw5Y,https://dev59.com/lnVC5IYBdhLWcg3wYQAp,http://stackoverflow.com/questions/4170295,https://dev59.com/VHRC5IYBdhLWcg3wCMc6 - tokland
2
我不确定在这种情况下“不切实际”甚至意味着什么。软件挑战通常是由于数据形状不切实际而导致的。考虑一种旧的数据组织方式,由于新的业务要求必须进行更改。像“不切实际”这样的判断充满了基于烟雾的假设和推测。 - user483040
显示剩余9条评论
3个回答

44

其实有一种非常简单但比较脆弱的方法,就是将它与自身的切片版本压缩在一起。

zipped = zip(mylist[0::2], mylist[1::2])

如果您不知道的话,最后一个切片参数就是“步长”。因此,我们从零开始选择列表中的每个第二项(1、3、5)。然后我们从一开始做同样的事情(2、4、6),并使用zip将它们制作成元组。


5
元素数量为奇数可能会产生意想不到的结果。此外,零长度的列表会表现不好。 - S.Lott
1
解决脆弱性的方法可能只需要这个小调整(如果您不介意在元素为奇数时出现空字符串)if len(mylist)%2 !=0: mylist.append('') ; zip(mylist[0::2], mylist[1::2]) - Aseem Yadav
1
zipped = itertools.zip_longest(mylist[0::2], mylist[1::2]) to pad odd length lists, default fillvalue=None - Steven Than

11

除了以上的答案,你还需要知道最简单的方法(如果你之前不知道的话)

l = [1, 2, 3, 4, 5, 6]
o = [(l[i],l[i+1]) for i in range(0,len(l),2)]

2
我完全忘记了range函数的可选步长参数。 - TartanLlama
为什么要从长度中减去2?这是错误的。 - SilentGhost
1
这将会默默地删除奇数长度列表的最后一个元素。这样做是否合适?或者应该引发某种异常? - S.Lott
1
肯定不会起作用,抛出了列表索引超出范围的异常。 - Sanjay Pradeep
2
这对我有效,被接受的答案却不行,但在我的情况下,列表总是偶数。 - OptimusPrime
显示剩余2条评论

6
直接引用来自Python文档中的itertools模块:

itertools模块是Python的一个标准库,提供了很多有用的迭代器工具。

from itertools import tee, izip

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

l = [1, 2, 3, 4, 5, 6]
for pair in pairwise(l):
    print pair

+1. 哎呀,这里出现了更强大的方式 :D - Skurmedel
8
这个并没有完全满足原帖的要求 - 它输出了 (1, 2), (2, 3), (3, 4), (4, 5), (5, 6),而不是 (1, 2), (3, 4), (5, 6) - Daniel Roseman
5
正确的函数是“grouper”,它在itertools配方中排名比这个函数稍低 ;) - Jochen Ritzel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接