5

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. For example:

List1 = ['A', 'B', 'C']
List2 = ['1', '2', '3']
List3 = ['A1', 'B2', 'C3']

I've seen quite a few other questions about simply combining two lists, but I'm afraid I haven't found anything that would achieve.

Any help would be much appreciated. Cheers.

5 Answers 5

11
>>> List1 = ['A', 'B', 'C']
>>> List2 = ['1', '2', '3']
>>> [x + y for x, y in zip(List1, List2)]
['A1', 'B2', 'C3']
Sign up to request clarification or add additional context in comments.

Comments

6
>>> List1 = ['A', 'B', 'C']
>>> List2 = ['1', '2', '3']
>>> map(lambda a, b: a + b, List1, List2)
['A1', 'B2', 'C3']

2 Comments

Not sure why this got downvoted; this works for Python 2. zip() is a better idea though.
Works like a charm - legendary stuff. Thanks mate!
5
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

Comments

3

To add to the variety (Python 2.7)

List3 = ['{}{}'.format(x, y) for x, y in  zip(List1, List2)]

2 Comments

@MartijnPieters, agreed it's overkill in this instance. Just presenting another option for those cases where formatting is actually needed
@ravoori you could motivate it with an example, like 'first: {} second: {}'.format
3

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 zipping 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']

1 Comment

you win the fastest runtime award!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.