Just recently came across the python `itertools`

“tools for efficient looping” again. Generators have the advantage of not creating the whole list on definition, but on demand (in contrast to e.g., list comprehensions). Really worth a look:

```
import itertools as it
g = it.cycle("abc") # a generator
g.next() # a
g.next() # b
g.next() # c
g.next() # a
g.next() # b
# ... and so on
g = it.cycle("abcde")
h = it.cycle("1234")
gh = it.izip(g,h) # iterzips n iterables together
gh.next() # (a,1)
gh.next() # (b,2)
# ... think about what this means with primes
gh.next() # (e,4)
gh.next() # (a,1)
# ...
```

Also very nice are the combinatoric generators:

```
it.product('ABCD', repeat=2) # AA AB AC AD BA BB BC BD
# CA CB CC CD DA DB DC DD
it.permutations('ABCD', 2) # AB AC AD BA BC BD CA CB CD DA DB DC
it.combinations('ABCD', 2) # AB AC AD BC BD CD
it.combinations_with_replacement('ABCD', 2) # AA AB AC AD BB BC BD CC CD DD
```

GüntherCool — I recently implemented the zip() function myself, thanks for the hint! 🙂

joernPost authorYou can also use generator expressions instead of izip:

[cc_python]

pairs = ( (i,j) for i in g for j in h )

pairs.next() # (a,1)

# …

[/cc_python]

And [cci_python]itertools.islice()[/cci_python] comes in handy if you just need to iterate over a (large*) part of the resulting list.

* you could use [cci_python]list(it.islice(pairs, 10))[/cci_python] if it’s small (here 10 first pairs).