Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #30397 > unrolled thread

Re: howto handle nested for

Started byLaszlo Nagy <gandalf@shopzeus.com>
First post2012-09-28 17:04 +0200
Last post2012-09-28 20:38 +0000
Articles 2 — 2 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: howto handle nested for Laszlo Nagy <gandalf@shopzeus.com> - 2012-09-28 17:04 +0200
    Re: howto handle nested for Neil Cerutti <neilc@norwich.edu> - 2012-09-28 20:38 +0000

#30397 — Re: howto handle nested for

FromLaszlo Nagy <gandalf@shopzeus.com>
Date2012-09-28 17:04 +0200
SubjectRe: howto handle nested for
Message-ID<mailman.1557.1348844688.27098.python-list@python.org>
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]

[toc] | [next] | [standalone]


#30428

FromNeil Cerutti <neilc@norwich.edu>
Date2012-09-28 20:38 +0000
Message-ID<acmg70F189sU1@mid.individual.net>
In reply to#30397
On 2012-09-28, Laszlo Nagy <gandalf@shopzeus.com> 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

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web