Reputation: 19164
I have two lists:
a = ['1', '2']
b = ['11', '22', '33', '44']
And I to combine them to create a list like the one below:
op = [('1', '11'), ('2', '22'), ('', '33'), ('', '44')]
How could I achieve this?
Upvotes: 4
Views: 674
Reputation: 2320
In Python 2.7: another way to do this:
[('', i[1]) if i[0] == None else i for i in map(None, a, b)]
For the example lists given in the question, this way is faster than using using 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
If the lists are longer and the non-existing value is to be filled with ''
then izip_longest
is significantly faster.
However, if you are content for the resulting list to be creating with a None
rather than a ''
, you don't need the list comprehension or the conditional: just map(None, a, b)
. Then the speed can be similar to that of izip_ilongest
for longer lists.
Note that when lists of unequal length are to be combined it is not necessarily the case that the result should take the length of the longer one. If you want a zip type function to always take the length of the first argument then the answers to the SO question "Is there a middle ground between `zip` and `zip_longest`" are illuminating.
Upvotes: -1
Reputation: 180411
You want itertools.zip_longest with a fillvalue
of an empty string:
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')]
For python2 it is izip_longest:
from itertools import izip_longest
print(list(izip_longest(a,b, fillvalue="")))
[('1', '11'), ('2', '22'), ('', '33'), ('', '44')]
If you just want to use the values you can iterate over the the izip object:
for i,j in izip_longest(a,b, fillvalue=""):
# do whatever
Some timings vs using map:
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
also creates another list using python2 so for large lists or if you have memory restrictions it is best avoided.
Upvotes: 9