Critique of first python code
George Sakkis
george.sakkis at gmail.com
Fri Feb 8 16:32:16 EST 2008
On Feb 8, 3:40 pm, Arnaud Delobelle <arno... at googlemail.com> wrote:
> On Feb 8, 7:20 pm, "Zack" <gol... at gmail.com> wrote:
>
>
>
> > Hi all. I'm just starting to pick up python. I wanted to play with nested
> > lists so first I wrote a little bit of code to create arbitrarily nested
> > lists (grow). Then I wrote a breadth first search. I'm putting this small
> > snippet up asking for criticism. Was there a more elegant way to do what I'm
> > doing? Anything that goes against convention? Anything that fingers me as a
> > c++ programmer? Are there standard modules that do these kind of things?
> > Thanks for any feedback.
>
> > ##############################
> > from random import randint
>
> > Val = 0
>
> > def grow(L,depth):
> > '''grows L by appending integers and arbitrarily nested lists with a
> > maximum
> > depth. Returns L.'''
> > global Val
> > if depth == 0:
> > return L
> > else:
> > choice = randint(1,2)
> > if 1 == choice:
> > # add a numerical literal
> > Val += 1
> > L.append(Val)
> > return grow(L,depth-1)
> > elif 2 == choice:
> > # add a list
> > L.append( grow([],depth-1) )
> > return grow(L,depth-1)
>
> How about:
>
> from itertools import count
> from random import randrange
>
> def grow(L, depth, counter=count()):
> '''grow L by appending integers and arbitrarily nested lists with a
> maximum depth. Returns L.'''
> if depth == 0:
> return L
> else:
> L.append(counter.next() if randrange(2) else grow([], depth-1))
> return grow(L, depth-1)
Or you may write a more flexible generator version of the above. If
you're not familiar with generators, think of them as lazy sequences
that generate successive elements only when needed:
import random
from itertools import count
def igrow(depth, next=count(1).next, nest=list, random=random.random):
'''Generate integers and arbitrarily nested iterables with a
maximum depth.'''
if depth:
depth -= 1
yield next() if random()<0.5 else
nest(igrow(depth,next,nest,random))
for e in igrow(depth,next,nest,random):
yield e
With this you can just as easily generate nested tuples (or other
containers) instead of lists:
nested = tuple(igrow(10, nest=tuple))
You may even avoid allocating nested containers altogether:
from types import GeneratorType
for x in igrow(10, nest=iter):
if isinstance(x, GeneratorType):
# process nested generator
else:
# x is an 'atom'
HTH,
George
More information about the Python-list
mailing list