Pregunta

A Python 3 learner here:

The question had the following accepted answer:

rr,tt = zip(*[(i*10, i*12) for i in xrange(4)])

which returns two tuples. I'd be grateful if someone could break down the answer and explain what it is doing with Python 3 in mind ( I know the range() returns an iterator in Python 3). I understand list comprehensions but I'm confused about unpacking (I thought you could only used a starred expression as part of an assignment target).

I'm equally confused by the code below. I understand the outcome and zipping (or think I do) but again the asterisk expression has got me beat.

x2, y2 = zip(*zip(x, y))

from this:

>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)
>>> list(zipped)
[(1, 4), (2, 5), (3, 6)]
>>> x2, y2 = zip(*zip(x, y))
>>> x == list(x2) and y == list(y2)
True
¿Fue útil?

Solución

*expression applies argument unpacking to the function call. It takes the expression part, which has to resolve to a iterable, and makes each element in that iterable a separate parameter to the function.

So, zip(x, y) returns an iterator (which is an iterable), and each element in that iterator is made an argument to the outer zip() function.

For zip(*[(i*10, i*12) for i in xrange(4)]) it is perhaps a little clearer; there are several elements here:

  • [(i*10, i*12) for i in xrange(4)] (should be range() in python 3) creates a list with 4 tuples, [(0, 0), (10, 12), (20, 24), (30, 36)]
  • The zip(*...) part then takes each of those 4 tuples and passes those as arguments to the zip() function.
  • zip() takes each tuple and pairs their elements; two elements per tuple means the result is 2 lists of 4 values each.

Because the zip() function produces two sequences, they can be assigned to the two variables.

I would have found the following a far more readable version of the same expression:

rr, tt = tuple(range(0, 40, 10)), tuple(range(0, 48, 12))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top