2015-04-03 128 views
3

这里是我要合并,创建一个新的列表中的两个列表合并两个列表:通过选择2元每

>>> 
>>> ls1 = [1, 2, 3, 4, 5] 
>>> ls2 = ['a', 'b', 'c', 'd'] 
>>> 

注:两个列表可能是不同的尺寸。

所需的输出:

[(1, 2, 'a', 'b'), (3, 4, 'c', 'd'), (5)] 

我尝试使用itertools.izip_longest但不能够实现它:

>>> list(itertools.izip_longest(ls1, ls2)) 
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, None)] 
>>> 

能否一些,一个把我扔在这一些轻。

感谢

回答

4

好的旧for循环怎么样?

result = [] 
for i in range(0, max(len(ls1),len(ls2)), 2): 
    result.append(tuple(ls1[i:i+2] + ls2[i:i+2])) 
+0

这是真棒:) – 2015-04-03 00:44:48

+2

如何良好的老_list comprehension_ ?:'结果= [元组(LS1 [I:+ 2] + LS2 [I:+ 2]),其中i在范围( 0,max(len(ls1),len(ls2)),2)]' – martineau 2015-04-03 01:46:04

3

你需要解决的最后一个条目(但你可以做到这一点很容易,因为你知道的ls1ls2的长度)。

>>> import itertools 
>>> ls1 = [1, 2, 3, 4, 5] 
>>> ls2 = ['a', 'b', 'c', 'd'] 
>>> list(itertools.izip_longest(ls1[0::2], ls1[1::2], ls2[0::2], ls2[1::2])) 
[(1, 2, 'a', 'b'), (3, 4, 'c', 'd'), (5, None, None, None)] 
1

如果你不关心有一些额外的无的,你可以使用iterizip_longest避免切片和创造新的列表:

ls1 = [1, 2, 3, 4, 5] 
ls2 = ['a', 'b', 'c', 'd'] 

it1 = iter(ls1) 
it2 = iter(ls2) 

zipped = izip_longest(it1, it1, it2, it2) 

print(list(zipped)) 
[(1, 2, 'a', 'b'), (3, 4, 'c', 'd'), (5, None, None, None)] 

或者使用filter删除从任何None's去年元组:

from itertools import izip_longest 

ls1 = [1, 2, 3, 4, 5] 
ls2 = ['a', 'b', 'c', 'd'] 

it1 = iter(ls1) 
it2 = iter(ls2 
zipped = list(izip_longest(it1, it1, it2, it2)) 
zipped[-1] = tuple(filter(lambda x: x is not None, zipped[-1])) 
[(1, 2, 'a', 'b'), (3, 4, 'c', 'd'), (5,)] 

对于较大的输入,你可以看到izip是相当多的有效的:

In [36]: ls1 = [1, 2, 3, 4, 5] * 1000000 
In [37]: ls2 = ['a', 'b', 'c', 'd'] * 1000000 
In [38]: %%timeit      
    it1 = iter(ls1) 
    it2 = iter(ls2) 
    zipped = list(izip_longest(it1, it1, it2, it2)) 
    zipped[-1] = tuple(filter(lambda x: x is not None, zipped[-1])) 
    ....: 
1 loops, best of 3: 224 ms per loop 

In [39]: %%timeit result = [] 
for i in xrange(0, max(len(ls1),len(ls2)), 2): 
    result.append(tuple(ls1[i:i+2] + ls2[i:i+2])) 
    ....: 
1 loops, best of 3: 1.46 s per loop 

In [40]: timeit list(itertools.izip_longest(ls1[0::2], ls1[1::2], ls2[0::2], ls2[1::2])) 
1 loops, best of 3: 404 ms per loop 

iter(ls1)创建一个迭代,以便传递it1, it1意味着我们将每两个元件配对从列表中,在内部蟒基本上指针我们每次迭代it1时间移动到下一个元素。

In [9]: ls2 = ['a', 'b', 'c', 'd']  
In [10]: it2 = iter(ls2)  
In [11]: next(it2), next(it2) # get first two elements 
Out[11]: ('a', 'b')  
In [12]: next(it2), next(it2) # again call next twice to get the 3rd and 4th elements 
Out[12]: ('c', 'd') 
+1

这也是一个非常好的主意。 – 2015-04-03 06:23:00

+0

你会介意如何izip_longest与迭代器一起工作。 – 2015-04-03 16:59:37

+1

@sapam,我在底部添加了一个示例。这里有很好的例子说明他们如何工作以及如何创建你自己的http://anandology.com/python-practice-book/iterators.html – 2015-04-03 17:13:04