views:

347

answers:

4

Basically, I would like to build a list comprehension over the "cartesian product" of two iterators. Think about the following Haskell code:

[(i,j) | i <- [1,2], j <- [1..4]]

which yields

[(1,1),(1,2),(1,3),(1,4),(2,1),(2,2),(2,3),(2,4)]

Can I obtain a similar behavior in Python in a concise way?

+8  A: 

Are you asking about this?

[ (i,j) for i in range(1,3) for j in range(1,5) ]
S.Lott
Yes sir, I was asking for that. I didn't know whether it was possible and what syntax to use, thank you.
Federico Ramponi
Sweet! I had totally missed this feature.
kigurai
+2  A: 

This seems to do what you describe:

[[a,b] for a in range(1,3) for b in range(1,5)]

UPDATE: Drat! Should have reloaded the page to see S.Lott's answer before posting. Hmmm... what to do for a little value-add? Perhaps a short testimony to the usefulness of interactive mode with Python.

I come most recently from a background with Perl so with issues like this I find it very helpful to type "python" at the command line and drop into interactive mode and just a)start trying things, and b)refine the niceties by hitting up-arrow and adjusting my previous attempt until I get what I want. Any time I'm hazy on some keyword, help is at hand. Just type: help("some_keyword"), read the brief summary, then hit "Q" and I'm back on line in direct conversation with the python interpreter.

Recommended if you are a beginner and not using it.

dvergin
+6  A: 

Cartesian product is in the itertools module (in 2.6).

>>> import itertools
>>> list(itertools.product(range(1, 3), range(1, 5)))
[(1, 1), (1, 2), (1, 3), (1, 4), (2, 1), (2, 2), (2, 3), (2, 4)]
Coady
+2  A: 

Fun fact about the nested comprehension: it mimics nested "for" loops, so the inner ones can use values from outer ones. This isn't useful in the cartesian product case, but good to know. For example:

[ (i,j) for i in range(10) for j in range(i) ]

generates all pairs (i,j) where 0>=i>j>10.

Rafał Dowgird
Even more interesting. Thank you!
Federico Ramponi