如何将列表转换为元组列表?

66

我是Python的新手,需要将一个列表转换成字典。我知道我们可以将元组列表转换为字典。

这是输入的列表:

L = [1,term1, 3, term2, x, term3,... z, termN]

我想将这个列表转换为一个元组列表(或直接转换成字典),如下所示:

[(1, term1), (3, term2), (x, term3), ...(z, termN)]

我们如何在Python中轻松地实现这一点?


1
对于字典,您可以简单地使用 dict(zip(*[iter(L)]*2)) - Grijesh Chauhan
7个回答

137
>>> L = [1, "term1", 3, "term2", 4, "term3", 5, "termN"]
# Create an iterator
>>> it = iter(L)
# zip the iterator with itself
>>> zip(it, it)
[(1, 'term1'), (3, 'term2'), (4, 'term3'), (5, 'termN')]

您想每次分组三个项目吗?

>>> zip(it, it, it)

你想将N个项目分成一组吗?

# Create N copies of the same iterator
it = [iter(L)] * N
# Unpack the copies of the iterator, and pass them as parameters to zip
>>> zip(*it)

2
有人能解释一下在这个上下文中 zip 是做什么的吗?我以为我知道它的工作原理,但显然不是,因为它没有给出 [(1,1,1),('term1','term1','term1'),...] - user1717828
9
每次访问迭代器都会推进其位置。在这里,zip将两个来自相同迭代器的物品配对。如果您编写了zip(iter(L), iter(L), iter(L)),它就会执行此操作,但通过分解iter的创建并共享它,您可以获得这种行为。 - Flexo
5
这在Python2中可以工作,但在Python3中,实际上需要将zip对象放入一个list中,例如:list(zip(it,it)),因为Python3不会评估zip,除非你明确要求它 - 请参见https://dev59.com/ZWIj5IYBdhLWcg3w6I89#19777642。 - Mani
哇,一开始不理解你在做什么,但现在我对你的解决方案是多么简单而美妙感到惊讶。 - winwin
嗯,zip 内部/隐式地将 list 转换为 iter 并在其上使用 next - Давид Шико

18

尝试使用组聚类习语:

zip(*[iter(L)]*2)

https://docs.python.org/2/library/functions.html
可保证可迭代对象的从左到右评估顺序。这使得使用zip(*[iter(s)]*n)将数据系列聚类成n长度组的习惯用法成为可能。

好的,我想我理解了你的代码,它与@thefourtheye的答案相同,只是你使用* 2来制作两个副本。我也可以写成zip(*(iter(L),) * 2) - Grijesh Chauhan
@GrijeshChauhan 是的,它是同样解决方案的缩写形式。 - Pablo Francisco Pérez Hidalgo
谢谢,非常有趣,您的代码只有17字节长 :) - Grijesh Chauhan
非常优雅和惯用的解决方案。谢谢! - Pavel Razgovorov
"可迭代对象的从左到右的评估顺序是有保证的。" 引用解释会得到赞!我终于明白了尽管使用了很多次!!每次迭代器被“评估”时,它都会“前进”到下一个元素。这就是/为什么我们将下一个元素作为元组的第二个元素获取。现在这一点非常明显! - Kai

12
使用 zip 将连续的偶数和奇数元素直接配对,以字典形式列出:
m = [ 1, 2, 3, 4, 5, 6, 7, 8 ] 
d = { x : y for x, y in zip(m[::2], m[1::2]) }

或者,既然您熟悉元组 -> 字典的转换方向:

d = dict(t for t in zip(m[::2], m[1::2]))

甚至:

d = dict(zip(m[::2], m[1::2]))

9

使用切片吗?

L = [1, "term1", 2, "term2", 3, "term3"]
L = zip(L[::2], L[1::2])

print L

这很棒,因为它使用了切片,简单易懂。 - user3486773

5
试试这个,
>>> L = [1, "term1", 3, "term2", 4, "term3", 5, "termN"]
>>> it = iter(L)
>>> [(x, next(it)) for x in it ]
[(1, 'term1'), (3, 'term2'), (4, 'term3'), (5, 'termN')]
>>> 

OR

>>> L = [1, "term1", 3, "term2", 4, "term3", 5, "termN"]
>>> [i for i in zip(*[iter(L)]*2)]
[(1, 'term1'), (3, 'term2'), (4, 'term3'), (5, 'termN')]

OR

>>> L = [1, "term1", 3, "term2", 4, "term3", 5, "termN"]
>>> map(None,*[iter(L)]*2)
[(1, 'term1'), (3, 'term2'), (4, 'term3'), (5, 'termN')]
>>> 

如果您想在迭代时编辑项目,这是一个很好的解决方案! - Iceflower S

4
[(L[i], L[i+1]) for i in xrange(0, len(L), 2)]

嘿,出现了以下错误: “Traceback (most recent call last): File "ab.py", line 105, in <module> print [(L[i], L[i+1]) for i in xrange(0, len(L), 2)] IndexError: list index out of range” - user3401408
@trex,你正在尝试使用奇数长度的L,根据你的问题,我认为你应该使用偶数长度的L。这将在Python2.X中起作用,在Python3.x中,你应该使用range而不是xrange。 - Grijesh Chauhan
@GrijeshChauhan 我正在使用Python2.7,所以我使用xrange。在Python2中,xrange是一个生成器,而range返回一个列表。对于一个很大的数n,Python2的range(n)会消耗大量内存。在Python3中,range变成了生成器,而xrange不再存在。 - Xing Fei
XingFei,是的,我理解这个问题了。我只是想回复@trex,建议如何使其无误执行。 - Grijesh Chauhan

2
下面的代码将处理偶数和奇数大小的列表:
[set(L[i:i+2]) for i in range(0, len(L),2)]

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