Difference between zip(list) and zip(*list)

PythonPython 3.x

Python Problem Overview


I am using a list p = [[1,2,3],[4,5,6]]

If I do :

>>>d=zip(p)
>>>list(d)
[([1, 2, 3],), ([4, 5, 6],)]

Though, what I actually want is obtained using this:

>>>d=zip(*p)
>>>list(d)
[(1, 4), (2, 5), (3, 6)]

I have found out that adding a '*' before the list name gives my required output, but I can't make out the difference in their operation. Can you please explain the difference?

Python Solutions


Solution 1 - Python

zip wants a bunch of arguments to zip together, but what you have is a single argument (a list, whose elements are also lists). The * in a function call "unpacks" a list (or other iterable), making each of its elements a separate argument. So without the *, you're doing zip( [[1,2,3],[4,5,6]] ). With the *, you're doing zip([1,2,3], [4,5,6]).

Solution 2 - Python

The * operator unpacks arguments in a function invocation statement.

Consider this

def add(x, y):
   return x + y

if you have a list t = [1,2], you can either say add(t[0], t[1]) which is needlessly verbose or you can "unpack" t into separate arguments using the * operator like so add(*t).

This is what's going on in your example. zip(p) is like running zip([[1,2,3],[4,5,6]]). Zip has a single argument here so it trivially just returns it as a tuple.

zip(*p) is like running zip([1,2,3], [4,5,6]). This is similar to running zip(p[0], p[1]) and you get the expected output.

Solution 3 - Python

The * character is known as the unpacking operator. when it appears behind an iterable object, what it does is passing the items inside the iterable to the function's caller one by one. In this case, since the zip function accepts a list of iterables in order to return their aligned columns, zip(*p) passes all the items inside the p as arguments to zip function:

Therefore, in this case, zip(*p) is equal to:

zip([1,2,3],[4,5,6])

Also, note that since Python-3.5 you can use unpacking operators in a few other cases than in function callers. One of which is called in-place unpacking that lets you use unpacking within another iterable.

In [4]: a = [1, 2, 3]

In [5]: b = [8, 9, *a, 0, 0]

In [6]: b
Out[6]: [8, 9, 1, 2, 3, 0, 0]

Solution 4 - Python

In a nutshell, with x = [1,2,3], when calling f(x), x receives 1 argument [1, 2, 3]. When you use the star operator f(*x), f receives three arguments, it is equivalent to the call f(1,2,3).

This is why, in Python's documentation, you will often see some_function(*args, **kwargs). Here the double star operator does the same, but for a dictionary: with d={"some_arg":2, "some_other_arg":3}, calling f(**d) is the same as f(some_arg=2, some_other_arg=3).

Now when you use zip, effectively you want to zip [1,2,3] with [4,5,6], so you want to pass 2 args to zip, therefore you need a star operator. Without it, you're passing only a single argument.

Solution 5 - Python

While this isn't the answer the question you asked, it should help. Since zip is used to combine two lists, you should do something like this list(zip(p[0], p[1])) to accomplish what you'd expect.

Solution 6 - Python

The "*" operator unpacks a list and applies it to a function. The zip function takes n lists and creates n-tuple pairs from each element from both lists:

> zip([iterable, ...]) > > This function returns a list of tuples, where the i-th tuple contains > the i-th element from each of the argument sequences or iterables. The > returned list is truncated in length to the length of the shortest > argument sequence. When there are multiple arguments which are all of > the same length, zip() is similar to map() with an initial argument of > None. With a single sequence argument, it returns a list of 1-tuples. > With no arguments, it returns an empty list.

Basically, by using * with [[1,2,3],[4,5,6]], you are passing [1,2,3] and [4,5,6] as arguments to zip.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser3735438View Question on Stackoverflow
Solution 1 - PythonSneftelView Answer on Stackoverflow
Solution 2 - PythonNoufal IbrahimView Answer on Stackoverflow
Solution 3 - PythonMazdakView Answer on Stackoverflow
Solution 4 - PythonvermillonView Answer on Stackoverflow
Solution 5 - PythontobloefView Answer on Stackoverflow
Solution 6 - PythongeneralpistonView Answer on Stackoverflow