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
Cool — I recently implemented the zip() function myself, thanks for the hint! 🙂
You 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).