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