12

Is there any smart way to write a list comprehension over more than one list?

I know I could use a separate range list as index but this way I have to know the length (or get it separately with a len() function call).

>>> a = range(10)
>>> b = range(10, 0, -1)
>>> [(a[x],b[x]) for x in range(10)]
[(0, 10), (1, 9), (2, 8), (3, 7), (4, 6), (5, 5), (6, 4), (7, 3), (8, 2), (9, 1)]

I'd love to have something like this:

>>> [(a,b) for a in range(10) and b in range(10, 0, -1)]
[(0, 10), (1, 9), (2, 8), (3, 7), (4, 6), (5, 5), (6, 4), (7, 3), (8, 2), (9, 1)]

How would you write the list comprehension? Is there a way to do this with itertools?

The range list just stand for any list and I do not necessarily want to get a tuple. there could also be a function which takes a and b as parameters. So zip is not what I want.

UPDATE: With "So zip is not what I want." I meant that I don't want zip(range(10), range(10, 0, -1))

dominik
  • 5,745
  • 6
  • 34
  • 45
  • Duplicate of [9184497](http://stackoverflow.com/questions/9184497/python-list-comprehension-function-with-arguments-in-two-lists)? – quazgar Apr 08 '13 at 07:30

2 Answers2

20

Your example is just:

zip(range(10), range(10, 0, -1))

More generally, you can join any set of iterables using zip:

[func(a, d, ...) for a, b, ..., n in zip(iterable1, iterable2, ..., iterableN)]
agf
  • 171,228
  • 44
  • 289
  • 238
  • 1
    The second solution is what I want. Thanks a lot. – dominik Mar 22 '12 at 16:58
  • You might want to consider [`itertools.izip`](http://docs.python.org/library/itertools.html#itertools.izip) since it is better at large sequences. Same idea, just a slightly different tool. – D.Shawley Mar 22 '12 at 17:01
  • I think you might've meant to write `[func(a, b, ...) for a, b, ..., n in zip(iterable1, iterable2, ..., iterableN)]` – Ryan J. Smith Aug 25 '15 at 17:32
1

If you want to apply a function to several sequences, you need either map or itertools.imap:

map(lambda *x: sum(x), range(10), range(10, 0, -1), range(0,20, 2))

There is no need to zip unless you prefer to do your mapping in a list comprehension

Marcin
  • 48,559
  • 18
  • 128
  • 201
  • That's not what he wants. Look at his second example -- he wants to `zip`. And you never need `map`, a list comprehension / generator expression can do everything it can and more. – agf Mar 22 '12 at 21:52
  • 1
    @agf " there could also be a function which takes a and b as parameters. So zip is not what I want." You could argue that one also never needs zip, because map is available. – Marcin Mar 22 '12 at 21:57
  • He wrote that before I added my second example, showing how to use a function with `zip`. Read his comment on my answer written after I added it. He meant he didn't want _just_ `zip`, not that he didn't want `zip` at all. – agf Mar 22 '12 at 21:59
  • @agf Why zip and apply a function when you can do it in one step? – Marcin Mar 22 '12 at 22:04
  • Because a list comprehension is more flexible and Pythonic. You can write the expression as a function, but you don't have to. You can use the included filtering expression rather than having to use a separate `filter` step. – agf Mar 22 '12 at 22:11
  • @agf Not every sequence needs to be filtered. – Marcin Mar 22 '12 at 22:21