On Sep 5, 1:37 pm, James Stroud <[EMAIL PROTECTED]> wrote: > Karthik Gurusamy wrote: > > On Sep 5, 11:17 am, James Stroud <[EMAIL PROTECTED]> 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/ -- http://mail.python.org/mailman/listinfo/python-list