5

I have a fairly last list of data like this:

data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

I'm trying to zip it so that that I get something like this:

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

I know I could do that with

l = [(data[0]), (data[1]), (data[2])]
zipped_data = zip(*l)

But I would like to write a list comprehension to do that for any number of items in data. I tried this, but it didn't work.

s = [zip(i) for i in data]
s
[[(1,), (2,), (3,)], [(4,), (5,), (6,)], [(7,), (8,), (9,)]]

Can anyone identify where I've gone wrong here? Thanks.

3 Answers3

14

Try the *:

In [2]: lis=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

In [3]: zip(*lis)
Out[3]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
2

If you really want to rewrite zip as a list comprehension, then this is how I would do it:

In [25]: data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

In [26]: [tuple(lis[j] for lis in data) for j in range(min(len(l) for l in data))]
Out[26]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

In [27]: data = [[1, 2, 3], [4, 5, 6], [7, 8]]

In [28]: [tuple(lis[j] for lis in data) for j in range(min(len(l) for l in data))]
Out[28]: [(1, 4, 7), (2, 5, 8)]

Though, zip(*data) is definitely a better way to go about this

inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241
0

I would do it with zip but here is done with list comprehension

def zip_lists(lists):
    """
        Assuming all lists have the same length

        >>> zip_lists([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
        [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

        >>> zip_lists([[1, 2], [3, 4], [5, 6], [7, 8]])
        [[1, 3, 5, 7], [2, 4, 6, 8]]

    """
    return [[l[x] for l in lists] for x in range(len(lists[0]))]
Facundo Casco
  • 10,065
  • 8
  • 42
  • 63