How to merge lists into a list of tuples?
Asked Answered
R

10

366

What is the Pythonic approach to achieve the following?

# Original lists:

list_a = [1, 2, 3, 4]
list_b = [5, 6, 7, 8]

# List of tuples from 'list_a' and 'list_b':

list_c = [(1,5), (2,6), (3,7), (4,8)]

Each member of list_c is a tuple, whose first member is from list_a and the second is from list_b.

Radiothermy answered 9/3, 2010 at 7:51 Comment(0)
B
555

In Python 2:

>>> list_a = [1, 2, 3, 4]
>>> list_b = [5, 6, 7, 8]
>>> zip(list_a, list_b)
[(1, 5), (2, 6), (3, 7), (4, 8)]

In Python 3:

>>> list_a = [1, 2, 3, 4]
>>> list_b = [5, 6, 7, 8]
>>> list(zip(list_a, list_b))
[(1, 5), (2, 6), (3, 7), (4, 8)]
Bustard answered 9/3, 2010 at 7:52 Comment(5)
you have to know that the zip function stops at the end of the shortest list, which may not be always what you want. the itertools module defines a zip_longest() method which stops at the end of the longest list, filling missing values with something you provide as a parameter.Bindle
@Adrien: cheers for your applicable comment. For Python 2.x, s/zip_longest()/izip_longest(). Renamed in Python 3.x to zip_longest().Peacemaker
could I create [(1,5), (1,6), (1,7), (1,8), (2,5), (2,6) ,so on] using zip command?Eccentricity
@MonaJalal: no, that's not pairing up, that's creating the product of the lists. itertools.product() does that.Bryna
note, at least in python3.6 zip does not return a list. So you need list(zip(list_a,list_b)) insteadWohlen
D
147

In python 3.0 zip returns a zip object. You can get a list out of it by calling list(zip(a, b)).

Diaconal answered 28/2, 2011 at 19:26 Comment(1)
This might be trivial, but be warned that using this directly in a for loop gives you a generator that will be exhausted after using it once. Save into a variable if you want to use it more oftenJempty
E
16

You can use map lambda

a = [2,3,4]
b = [5,6,7]
c = map(lambda x,y:(x,y),a,b)

This will also work if there lengths of original lists do not match

Emmyemmye answered 4/7, 2015 at 5:49 Comment(6)
Why use a lambda? map(None, a,b)Gery
I only have have access to python 3.5.Emmyemmye
If you were using python3 then c would not be a list it would be a map object, also using a lambda is going to be a lot less efficient than just zipping, if you have different length lists and want to handle that then you would use izip_longest/zip_longestGery
it does not work when "lengths of original lists do not match".Levkas
In [56]: a = ("a","b","c","d","e") In [57]: b = (1,2,3,4,5,6,7,8,9,10) In [58]: s = list(map(lambda x,y:(x,y),a,b)) In [59]: print(s) [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] No issue for me with miss matched lengthsWeighted
Hi @DarkKnight: Thank you for the solution. lambda works for me. I am thinking of creating a function by passing multiple lists/arguments in the form of *args. is there any dynamic way to zip multiple lists depending on different scenarios?Pourboire
P
8

Youre looking for the builtin function zip.

Pantalets answered 9/3, 2010 at 7:55 Comment(0)
J
7

I am not sure if this a pythonic way or not but this seems simple if both lists have the same number of elements :

list_a = [1, 2, 3, 4]

list_b = [5, 6, 7, 8]

list_c=[(list_a[i],list_b[i]) for i in range(0,len(list_a))]
Jeepers answered 11/9, 2018 at 7:51 Comment(0)
C
6

The output which you showed in problem statement is not the tuple but list

list_c = [(1,5), (2,6), (3,7), (4,8)]

check for

type(list_c)

considering you want the result as tuple out of list_a and list_b, do

tuple(zip(list_a,list_b)) 
Callender answered 12/5, 2016 at 14:52 Comment(2)
From my point of view, it seem's what I'm looking for and to work fine for the both (list and tuple). Because when you use print, you will see the right value (as expected and mentionned by @Callender and @Lodewijk) and nothing related to the object such as : <map object at 0x000001F266DCE5C0> or <zip object at 0x000002629D204C88>. At least, the solution about map and zip (alone) seem's to be incomplete (or too complicated) for me.Distributive
The question states they want a list of tuples not a tuple of tuples.Twocolor
S
5

I know this is an old question and was already answered, but for some reason, I still wanna post this alternative solution. I know it's easy to just find out which built-in function does the "magic" you need, but it doesn't hurt to know you can do it by yourself.

>>> list_1 = ['Ace', 'King']
>>> list_2 = ['Spades', 'Clubs', 'Diamonds']
>>> deck = []
>>> for i in range(max((len(list_1),len(list_2)))):
        while True:
            try:
                card = (list_1[i],list_2[i])
            except IndexError:
                if len(list_1)>len(list_2):
                    list_2.append('')
                    card = (list_1[i],list_2[i])
                elif len(list_1)<len(list_2):
                    list_1.append('')
                    card = (list_1[i], list_2[i])
                continue
            deck.append(card)
            break
>>>
>>> #and the result should be:
>>> print deck
>>> [('Ace', 'Spades'), ('King', 'Clubs'), ('', 'Diamonds')]
Sawicki answered 17/2, 2014 at 10:1 Comment(1)
Changing one of the input lists (if they differ in length) is not a nice side-effect. Also, the two assignments to card in the if-elif are not needed, that’s why you have the continue. (In fact, without the continue you wouldn’t have to change the lists: both earlier mentioned assignments should then be kept and become card = (list_1[i], '') and card = ('', list_2[1]) respectively.)Conover
O
2

Or map with unpacking:

>>> list(map(lambda *x: x, list_a, list_b))
[(1, 5), (2, 6), (3, 7), (4, 8)]
>>> 
Overdraw answered 9/11, 2021 at 5:39 Comment(0)
J
1

One alternative without using zip:

list_c = [(p1, p2) for idx1, p1 in enumerate(list_a) for idx2, p2 in enumerate(list_b) if idx1==idx2]

In case one wants to get not only tuples 1st with 1st, 2nd with 2nd... but all possible combinations of the 2 lists, that would be done with

list_d = [(p1, p2) for p1 in list_a for p2 in list_b]
Jaenicke answered 15/5, 2018 at 13:57 Comment(0)
G
0

Like me, if anyone needs to convert it to list of lists (2D lists) instead of list of tuples, then you could do the following:

list(map(list, list(zip(list_a, list_b))))

It should return a 2D List as follows:

[[1, 5], 
 [2, 6], 
 [3, 7], 
 [4, 8]]
Gintz answered 15/1, 2022 at 6:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.