2011-05-15 79 views
3

我刚刚使用python从列表中提取了一些数据,但认为这是过度复杂和不合理的,并且可能有更好的方法来完成此操作。我确实很确定我在标准库文档的某个地方看到了这一点,但我的大脑拒绝告诉我在哪里。从列表中获取两元组

所以这里有云:

输入:

x = range(8) # any even sequence 

输出:

[[0, 1], [2, 3], [4, 5], [6, 7]] 

我的看法:

[ [x[i], x[i+1]] for i in range(len(x))[::2] ] 
+0

你说二元组,但你的例子是“双列表” – 2011-05-15 10:14:09

+1

重复(很多次):http://stackoverflow.com/questions/434287/what-is-the-most-pythonic-way-重复列表块 – tokland 2011-05-15 10:15:14

+0

当然,糟糕的是混淆。尽管这个问题并不重要;) – c089 2011-05-15 10:28:43

回答

7

元组?

在Python 2 ň

>>> zip(*2*[iter(x)]) 
[(0, 1), (2, 3), (4, 5), (6, 7)] 

在Python 3 ň

zip()表现略有不同...

>> zip(*2*[iter(x)]) 
<zip object at 0x285c582c> 
>>> list(zip(*2*[iter(x)])]) 
[(0, 1), (2, 3), (4, 5), (6, 7)] 

名单?

执行是在Python 2和3一样的...

>>> [[i,j] for i,j in zip(*2*[iter(x)])] 
[[0, 1], [2, 3], [4, 5], [6, 7]] 

,或者:

>>> [list(t) for t in zip(*2*[iter(x)])] 
[[0, 1], [2, 3], [4, 5], [6, 7]] 

,如果你想分成list S的3后者是更有益或多种元素,而不拼写出来,如:

>>> [list(t) for t in zip(*4*[iter(x)])] 
[[0, 1, 2, 3], [4, 5, 6, 7]] 

如果zip(*2*[iter(x)])对你来说看起来有点奇怪(当我第一次看到它时,它确实对我有用!),看看How does zip(*[iter(s)]*n) work in Python?

另请参阅this pairwise implementation,我认为它很整洁。

+0

这实际上非常优雅(但有点难以阅读)。感谢所有的答案,学到了很多:) – c089 2011-05-15 13:46:42

+0

我发现'zip(* [iter(s)] * n)'相当丑陋,但这个习语是在[文档](http://docs.python.org/ library/functions.html#zip),所以我猜它是Pythonic。对于对,我喜欢我链接到的'pairwise()'版本。 [美丽胜于丑陋](http://www.python.org/dev/peps/pep-0020/),对不对? – Johnsyweb 2011-05-15 21:43:39

0

你可以把它改写了一下:

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

对于一些列表任务,你可以使用itertools,但我很确定这个没有帮助函数。

1

如果你想元组而不是列表,你可以尝试:

>>> zip(range(0, 8, 2), range(1, 8, 2)) 
[(0, 1), (2, 3), (4, 5), (6, 7)] 
1

输入:

x = range(8) # any even sequence 

解决方案:

output = [] 
for i, j in zip(*[iter(x)]*2): 
    output.append([i, j]) 

输出:

print output 
[[0, 1], [2, 3], [4, 5], [6, 7]]