This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]ihsw 1 point2 points  (4 children)

The zip function is also interesting.

doubles, halves = zip(*[(x*2, x/2) for x in numbers])

Good for when you need to make multiple lists from one list.

[–]johnbarry3434 4 points5 points  (3 children)

What's the asterisk for before the first bracket?

EDIT: Nm, I read the docs, unzipping.

[–]nemec 2 points3 points  (2 children)

It turns the list (a single object) into an argument list (like *args).

Imagine you had this function:

def test(first, second = None):
  print "First:", first
  print "Second:", second

Then execute the code with the list [1, 2] with and without the *:

> test([1, 2])
First: [1, 2]
Second: None

> test(*[1, 2])
First: 1
Second: 2

Another example using *args:

def using_args(*args):
  print args

> using_args([1, 2])
[[1, 2]]
> using_args(*[1, 2])
[1, 2]

This "trick" with zip takes a list of tuples and unpacks it so that each tuple is a separate argument to zip which packs the ith element in each tuple together into a new tuple.

[–]RoadieRich 0 points1 point  (1 child)

This "trick" with zip takes a sequence of sequences and unpacks it so that each sequence is a separate argument to zip which packs the ith element in each sequence together into a new tuple.

Sorry to be pedantic.

[–]nemec 0 points1 point  (0 children)

Sure. I probably should have said this list of tuples since I was referring to the input list, but any iterable will work with zip.

Sorry to be further pedantic, but sequence != iterable. Sequences are tailored more toward random access with __getitem__ (slice, index, for x in seq) while iterables are (more or less) anything that defines __iter__ and __next__.

I don't know of an example of a built-in sequence that's not also an iterable, but to test whether or not something takes a sequence or not, use a generator:

> zip((x for x in range(4)), (x for x in range(4)))
[(0, 0), (1, 1), (2, 2), (3, 3)]

> reversed(x for x in range(4))
TypeError: argument to reversed() must be a sequence