i need to iterate over a tuple of indices. all indices must be in the range
[0, N) with the condition i > j. The toy example I present here deal
a somewhat 'hacky' attempt using eval (just adding this for completeness. there are nicer answers here!).
the idea is to construct a string like
'((a, b, c) for a in range(5) for b in range(a) for c in range(b))'
and return the eval of that:
def ijk_eval(n, depth):
'''
construct a string representation of the genexpr and return eval of it...
'''
var = string.ascii_lowercase
assert len(var) >= depth > 1 # returns int and not tuple if depth=1
for_str = ('for {} in range({}) '.format(var[0], n) +
' '.join('for {} in range({})'.format(nxt, cur)
for cur, nxt in zip(var[:depth-1], var[1:depth])))
return eval('(({}) {})'.format(', '.join(var[:depth]), for_str))
can be used this way and produces the right results.
for i, j in ijk_eval(n=5, depth=2):
print(i, j)
the construction is not very nice - but the result is: it is a regular genexpr and just as efficient as those are.