2015-04-24 148 views
4

的名单上有两个列表:合并两个列表成为名单

a = ['1', '2'] 
b = ['11', '22', '33', '44'] 

我结合他们创造类似下面的列表:

op = [('1', '11'), ('2', '22'), ('', '33'), ('', '44')] 

我怎么能做到这一点?

回答

9

你想itertools.zip_longest为空字符串的fillvalue

a = ['1', '2'] 
b = ['11', '22', '33', '44'] 

from itertools import zip_longest # izip_longest for python2 

print(list(zip_longest(a,b, fillvalue=""))) 
[('1', '11'), ('2', '22'), ('', '33'), ('', '44')] 

对于python2是izip_longest

from itertools import izip_longest 

print(list(izip_longest(a,b, fillvalue=""))) 
[('1', '11'), ('2', '22'), ('', '33'), ('', '44')] 

如果你只是想用就可以遍历值izip物件:

for i,j in izip_longest(a,b, fillvalue=""): 
    # do whatever 

一些计时VS使用地图:

In [51]: a = a * 10000 

In [52]: b = b * 9000 

In [53]: timeit list(izip_longest(a,b,fillvalue="")) 
100 loops, best of 3: 1.91 ms per loop 

In [54]: timeit [('', i[1]) if i[0] == None else i for i in map(None, a, b)] 
100 loops, best of 3: 6.98 ms per loop 

map还创建使用python2因此对于大名单,或者如果你拥有它,最好避免内存限制的另一个列表。

+1

它说不能导入名称zip_longest – sam

+0

'izip_longest for python2' –

+1

我正在使用python 2.7 – sam

-1

在Python 2.7:另一种方式来做到这一点:

[('', i[1]) if i[0] == None else i for i in map(None, a, b)] 

对于这个问题给出的示例清单,这样比使用izip_longest使用速度更快:

>>> timeit.timeit("[('', i[1]) if i[0] == None else i for i in map(None, a, b)]", 'from __main__ import a, b') 
1.3226220607757568 

>>> timeit.timeit("list(itertools.izip_longest(a, b, fillvalue=''))", 'from __main__ import a, b') 
1.629504919052124 

如果名单更长且不存在的值将被填充''然后izip_longest明显更快。

但是,如果您的内容是使用None而不是''创建结果列表,则不需要列表理解或条件:只需map(None, a, b)。然后,对于较长的列表,速度可以类似于izip_ilongest

请注意,当要组合不等长的列表时,结果不一定是长度较长的结果。如果你想要一个zip类型的函数总是取第一个参数的长度,那么对SO问题“Is there a middle ground between `zip` and `zip_longest`”的回答就会变得很明显。