Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

howto handle nested for

59 views
Skip to first unread message

Neal Becker

unread,
Sep 28, 2012, 10:39:32 AM9/28/12
to pytho...@python.org
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?

Alister

unread,
Sep 28, 2012, 10:42:20 AM9/28/12
to
It definitely looks like for is the wrong way to go for this
without more information on the reason why it is difficult to say what
the correct approach would be



--
Calm down, it's *____ only* ones and zeroes.

Wojtek

unread,
Sep 28, 2012, 10:51:07 AM9/28/12
to
W dniu 2012-09-28 16:42, Alister pisze:
it's well described in head first: python book ;)
check this sources from this book
http://www.headfirstlabs.com/books/hfpython/code/chapter1.zip

hope it helps,

regards

Laszlo Nagy

unread,
Sep 28, 2012, 11:04:38 AM9/28/12
to pytho...@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]


Tim Chase

unread,
Sep 28, 2012, 11:28:21 AM9/28/12
to Neal Becker, pytho...@python.org
On 09/28/12 09: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?

There was a good discussion on this back in 2008 that might be worth
reading over. For some reason the mail.python.org archives[1] seem
to have broken threading on this topic (Andrew Reedick's reply using
exec() is waaay down in the archive, disassociated from the thread),
so here it is archived somewhere else where the 2 pages of threading
seems more manageable/accurate:

http://www.velocityreviews.com/forums/t585147-creating-unique-combinations-from-lists.html

-tkc

[1]
http://mail.python.org/pipermail/python-list/2008-January/487851.html





Ian Kelly

unread,
Sep 28, 2012, 11:49:36 AM9/28/12
to Python
On Fri, Sep 28, 2012 at 8:39 AM, Neal Becker <ndbe...@gmail.com> 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?

levels = 6
for combination in itertools.product(xrange(n_syms), levels):
# do stuff

Cheers,
Ian

Neal Becker

unread,
Sep 28, 2012, 11:52:36 AM9/28/12
to pytho...@python.org
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?

Thanks for the suggestions: I found itertools.product is just great for this.

Peter Otten

unread,
Sep 28, 2012, 11:53:54 AM9/28/12
to pytho...@python.org
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?

for s in itertools.product(range(n_syms), repeat=6):
print s

Neil Cerutti

unread,
Sep 28, 2012, 4:38:56 PM9/28/12
to
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

Peter Pearson

unread,
Sep 28, 2012, 9:15:24 PM9/28/12
to
On Fri, 28 Sep 2012 09:49:36 -0600, Ian Kelly <ian.g...@gmail.com> wrote:
>
> levels = 6
> for combination in itertools.product(xrange(n_syms), levels):
> # do stuff

>>> n_syms = 3
>>> levels = 6
>>> for combination in itertools.product(xrange(n_syms), levels):
... print combination
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable


--
To email me, substitute nowhere->spamcop, invalid->net.

Hans Mulder

unread,
Sep 29, 2012, 8:41:40 AM9/29/12
to
On 29/09/12 03:15:24, Peter Pearson wrote:
> On Fri, 28 Sep 2012 09:49:36 -0600, Ian Kelly <ian.g...@gmail.com> wrote:
>>
>> levels = 6
>> for combination in itertools.product(xrange(n_syms), levels):
>> # do stuff
>
>>>> n_syms = 3
>>>> levels = 6
>>>> for combination in itertools.product(xrange(n_syms), levels):
> ... print combination
> ...
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> TypeError: 'int' object is not iterable

>>> n_syms = 3
>>> levels = 6
>>> for combination in itertools.product(xrange(n_syms), repeat=levels):
... print combination
...
(0, 0, 0, 0, 0, 0)
(0, 0, 0, 0, 0, 1)
(0, 0, 0, 0, 0, 2)
(0, 0, 0, 0, 1, 0)
(0, 0, 0, 0, 1, 1)
(0, 0, 0, 0, 1, 2)
(0, 0, 0, 0, 2, 0)
(0, 0, 0, 0, 2, 1)
(0, 0, 0, 0, 2, 2)
(0, 0, 0, 1, 0, 0)

etc.


Hope this helps,

-- HansM



0 new messages