Ethan Furman wrote: > Steven D'Aprano wrote: >> On Thu, 23 Feb 2012 16:30:09 -0800, Alex Willmer wrote: >> >>> This week I was slightly surprised by a behaviour that I've not >>> considered before. I've long used >>> >>> for i, x in enumerate(seq): >>> # do stuff >>> >>> as a standard looping-with-index construct. In Python for loops don't >>> create a scope, so the loop variables are available afterward. I've >>> sometimes used this to print or return a record count e.g. >>> >>> for i, x in enumerate(seq): >>> # do stuff >>> print 'Processed %i records' % i+1 >>> >>> However as I found out, if seq is empty then i and x are never created. >> >> This has nothing to do with enumerate. It applies to for loops in >> general: the loop variable is not initialised if the loop never runs. >> What value should it take? Zero? Minus one? The empty string? None? >> Whatever answer Python choose would be almost always wrong, so it refuses >> to guess. >> >> >>> The above code will raise NameError. So if a record count is needed, and >>> the loop is not guaranteed to execute the following seems more correct: >>> >>> i = 0 >>> for x in seq: >>> # do stuff >>> i += 1 >>> print 'Processed %i records' % i >> >> What fixes the problem is not avoiding enumerate, or performing the >> increments in slow Python instead of fast C, but that you initialise the >> loop variable you care about before the loop in case it doesn't run. >> >> i = 0 >> for i,x in enumerate(seq): >> # do stuff >> >> is all you need: the addition of one extra line, to initialise the loop >> variable i (and, if you need it, x) before hand. > > Actually, > > i = -1 > > or his reporting will be wrong.
Yes, either i = -1 for i, x in enumerate(seq): ... print "%d records" % (i+1) or i = 0 for i, x in enumerate(seq, 1): ... print "%d records" % i -- http://mail.python.org/mailman/listinfo/python-list