Velocity Reviews > Re: howto handle nested for

Re: howto handle nested for

Laszlo Nagy
Guest
Posts: n/a

 09-28-2012
On 2012-09-28 16:39, Neal Becker wrote:
> I know this should be a fairly basic question, but I'm drawing a blank.
>
> I have code that looks like:
>
> for s0 in xrange (n_syms):
> for s1 in xrange (n_syms):
> for s2 in xrange (n_syms):
> for s3 in xrange (n_syms):
> for s4 in range (n_syms):
> for s5 in range (n_syms):
>
> Now I need the level of nesting to vary dynamically. (e.g., maybe I need to add
> for s6 in range (n_syms))
>
> Smells like a candidate for recursion. Also sounds like a use for yield. Any
> suggestions?
>

In your example, it seem that the iterable of the for loop is always the
same: range(n_sysms). It seems to be a number. Is that true? If that is
so, then here is something useful:

import copy

class MultiLevelIterator(object):
def __init__(self,levels,n):
assert(levels>0)
assert(n>0)
self.levels = levels
self.values = [0]*levels
self.n = n

def __iter__(self):
return self

def next(self):
res = copy.copy(self.values)
idx = self.levels-1
while idx>=0:
self.values[idx]+=1
if self.values[idx]>=self.n:
self.values[idx] = 0
idx-=1
else:
return res
raise StopIteration

i = MultiLevelIterator(2,3)
for values in i:
print values

This will print:

[0, 0]
[0, 1]
[0, 2]
[1, 0]
[1, 1]
[1, 2]
[2, 0]
[2, 1]

Neil Cerutti
Guest
Posts: n/a

 09-28-2012
On 2012-09-28, Laszlo Nagy <(E-Mail Removed)> wrote:
> In your example, it seem that the iterable of the for loop is
> always the same: range(n_sysms). It seems to be a number. Is
> that true? If that is so, then here is something useful:
>
> import copy
>
> class MultiLevelIterator(object):
> def __init__(self,levels,n):
> assert(levels>0)
> assert(n>0)
> self.levels = levels
> self.values = [0]*levels
> self.n = n
>
> def __iter__(self):
> return self
>
> def next(self):
> res = copy.copy(self.values)
> idx = self.levels-1
> while idx>=0:
> self.values[idx]+=1
> if self.values[idx]>=self.n:
> self.values[idx] = 0
> idx-=1
> else:
> return res
> raise StopIteration
>
> i = MultiLevelIterator(2,3)
> for values in i:
> print values
>
> This will print:
>
> [0, 0]
> [0, 1]
> [0, 2]
> [1, 0]
> [1, 1]
> [1, 2]
> [2, 0]
> [2, 1]

It looks like you might have missed the last one. Also, be sure
to check itertools for occasionally for cool stuff like this.

>>> for values in itertools.product(range(3), repeat=2):

.... print(values)
....
(0, 0)
(0, 1)
(0, 2)
(1, 0)
(1, 1)
(1, 2)
(2, 0)
(2, 1)
(2, 2)

--
Neil Cerutti