I have two lists that I would like to combine, but instead of increasing the number of items in the list, I\'d actually like to join the items that have a matching index. Fo
As can be seen from the many other answers, there are multiple ways to solve this in python. Here's one such example:
>>> from operator import add
>>> List1 = ['A', 'B', 'C']
>>> List2 = ['1', '2', '3']
>>> map(add, List1, List2)
['A1', 'B2', 'C3']
What you're essentially looking for though, is zipWith, I link to hoogle only because it is easily explainable, and there's no standard implementation of zipWith in python. What it is saying is you supply zipWith
a binary function, e.g. operator.add
, and two lists, and it returns the lists zip
'd together with the function applied to each pair.
You can abstract this idea out to operate on more than just two lists with a binary operator.
>>> def zipWith(f, *iterables):
... return map(f, *iterables)
Aside: This may seem like it's not doing much, but it is providing semantics about what is happening. It is zip
ping the iterables with the function. This is more readable than just using the map version.
Then you can use it with any function so long as you match the number of input lists to the arity of the function f
. For example:
>>> zipWith(lambda a, b, c: a + b * c, [1, 2, 3], [1, 2, 3], [1, 2, 3])
[2, 6, 12]
>>> zipWith(lambda a, b, c: (a + b) * c, List1, List2, [1, 2, 3])
['A1', 'B2B2', 'C3C3C3']
>>> zipWith(lambda a, b: a + b, List1, List2)
['A1', 'B2', 'C3']
>>> zipWith(add, List1, List2)
['A1', 'B2', 'C3']
>>> List1 = ['A', 'B', 'C']
>>> List2 = ['1', '2', '3']
>>> map(lambda a, b: a + b, List1, List2)
['A1', 'B2', 'C3']
map(''.join,zip(List1,List2,List3))
>>>
['A1A1', 'B2B2', 'C3C3']
Explanation:
zip(List1,List2,List3)
Returns
[('A', '1', 'A1'), ('B', '2', 'B2'), ('C', '3', 'C3')]
Each tuple repesents the elements associated with an index N
in the zipped lists. We want to combine the elements in each tuple into a single string. For a single tuple we can go:
>>> ''.join(('A', '1', 'A1'))
'A1A1'
To produce the desired result, hence to get a list of all the desired strings, we map this join
function to all the tuples like so:
map(''.join,zip(List1,List2,List3))
Resulting in
['A1A1', 'B2B2', 'C3C3']
So if you wanted to add only List1
and List2
map(''.join,zip(List1,List2))
>>>
['A1', 'B2', 'C3']
Some timeings:
Microsoft Windows [Version 6.2.9200]
(c) 2012 Microsoft Corporation. All rights reserved.
C:\Users\Henry>python -m timeit -s "List1 = ['A', 'B', 'C']*10**5; List2 = ['1', '2','3']*10**5" "map(lambda x, y: x + y, List1, List2)"
10 loops, best of 3: 44 msec per loop
C:\Users\Henry>python -m timeit -s "List1 = ['A', 'B', 'C']*10**5; List2 = ['1', '2', '3']*10**5" "[x + y for x, y in zip(List1, List2)]"
10 loops, best of 3: 44 msec per loop
C:\Users\Henry>python -m timeit -s "List1 = ['A', 'B', 'C']*10**5; List2 = ['1', '2', '3']*10**5" "map(''.join,zip(List1,List2))"
10 loops, best of 3: 42.6 msec per loop
C:\Users\Henry>python -m timeit -s "from operator import add" "List1 = ['A', 'B', 'C']*10**5; List2 = ['1', '2', '3']*10**5" "map(add, List1, List2)"
10 loops, best of 3: 28.6 msec per loop
And using izip instead of zip
Microsoft Windows [Version 6.2.9200]
(c) 2012 Microsoft Corporation. All rights reserved.
C:\Users\Henry>python -m timeit -s "List1 = ['A', 'B', 'C']*10**5; List2 = ['1', '2','3']*10**5" "map(lambda x, y: x + y, List1, List2)"
10 loops, best of 3: 44.1 msec per loop
C:\Users\Henry>python -m timeit -s "from itertools import izip" "List1 = ['A', 'B', 'C']*10**5; List2 = ['1', '2', '3']*10**5" "[x + y for x, y in izip(List1, List2)]"
10 loops, best of 3: 31.3 msec per loop
C:\Users\Henry>python -m timeit -s "from itertools import izip" "List1 = ['A', 'B', 'C']*10**5; List2 = ['1', '2', '3']*10**5" "map(''.join,izip(List1,List2))"
10 loops, best of 3: 36.2 msec per loop
C:\Users\Henry>python -m timeit -s "from operator import add" "List1 = ['A', 'B', 'C']*10**5; List2 = ['1', '2', '3']*10**5" "map(add, List1, List2)"
10 loops, best of 3: 28.6 msec per loop
>>> List1 = ['A', 'B', 'C']
>>> List2 = ['1', '2', '3']
>>> [x + y for x, y in zip(List1, List2)]
['A1', 'B2', 'C3']
To add to the variety (Python 2.7)
List3 = ['{}{}'.format(x, y) for x, y in zip(List1, List2)]