concise code (beginner)

Karthik Gurusamy kar1107 at gmail.com
Thu Sep 6 15:56:47 EDT 2007


On Sep 5, 1:37 pm, James Stroud <jstr... at mbi.ucla.edu> wrote:
> Karthik Gurusamy wrote:
> > On Sep 5, 11:17 am, James Stroud <jstr... at mbi.ucla.edu> wrote:
>
> >> for i in xrange(number_of_reads):
> >>    for dev in devs:
> >>      try:
> >>        _reader = getattr(dev, 'read%d' % i)
> >>        _reader()
> >>      except Exception, e:
> >>        print e
> >>        devs.remove(dev)
>
> > I see in many of the solutions suggested above, the devs sequence/
> > iterator is being modified while iterating. I know it is not defined
> > for interation over dictionary keys. Are they defined for other
> > collections like lists?
>
> Good eye! My code is broke as you have noticed:
>
> py> r = range(5)
> py> for i in r:
> ...   print i
> ...   if i % 2:
> ...     r.remove(i)
> ...
> 0
> 1
> 3
>
> For longer sequences, the algorithm I've used in these cases in the past
> goes something like this:
>
> py> r = range(10, 17)
> py> print r
> [10, 11, 12, 13, 14, 15, 16]
> py>
> py> i = 0
> py> while i < len(r):
> ...   j = r[i]
> ...   print j
> ...   if j % 2:
> ...     r.remove(j)
> ...   else:
> ...     i += 1
> ...
> 10
> 11
> 12
> 13
> 14
> 15
> 16
> py> print r
> [10, 12, 14, 16]
>
> Which would change my problematic code above to:
>
> for i in xrange(number_of_reads):
>    j = 0
>    while j < len(devs):
>      try:
>        _reader = getattr(devs[j], 'read%d' % i)
>        _reader()
>        j += 1
>      except Exception, e:
>        print e
>        devs.remove(dev)
>
> Another way is to make a copy of devs, if devs is short, which makes my
> problematic code into a matter of a "typo"--maybe I can make this claim
> to save some face?
>
> for i in xrange(number_of_reads):
>    for dev in devs[:]:
>      try:
>        _reader = getattr(dev, 'read%d' % i)
>        _reader()
>      except Exception, e:
>        print e
>        devs.remove(dev)
>

Thanks, personally I like this duplicate copy solution. It's cleaner
and easier on the eye/brain. (Moreover the C like first solution
assumes the collection is a sequence, which is not true for dictionary/
set like collections).

That said, it may be a good future language enhancement to define a
reasonable consistent behavior for an iterator over a changing
collection. This occurs quite common when we walk a collection and
usually delete the current item.

For a sequence, what the expected behavior is quite obvious (just
remove this element and go over to the next). For other collections
like dictionary/set, again if the operation is delete, the expected
behavior is obvious. If we are doing insertion, for sequence a well-
defined behavior can be formulated (based on insert before or after
current position -- if after we will see it in the walk, if before we
won't see it) . For dict/set I see this isn't simple (as based on hash
key we may insert ahead or later of the current 'cursor'/position.

Karthik



> James
>
> --
> James Stroud
> UCLA-DOE Institute for Genomics and Proteomics
> Box 951570
> Los Angeles, CA 90095
>
> http://www.jamesstroud.com/





More information about the Python-list mailing list