ADB
ADB

Reputation: 21

Python enumerate - what cannot I see?

Can anyone explain what is going on here as I am flummoxed

I have a module-wide list variable with elements that have fields - mylist with 'n' entries, each of field1, field2..fieldx

I want to access them in a procedure, so have (with some trace/debug statements)

print mylist [1].dataFieldCheckType

for lIndex, lField in enumerate(mylist, start = 1):

    print lField.dataFieldCheckType

The first print statement gives the value -4 (which is correct), the second gives a different value, 0, over a simple one-statement step. To my mind, lField is being created as a new element with default values but I do not know, nor understand, why. Why is the second print statement giving a different value from the first?

What am I doing wrong? Or, probably more pertinently, what am I not understanding?

I have asked this in another forum but no-one has come up with a plausible explanation.

Upvotes: 2

Views: 165

Answers (2)

timgeb
timgeb

Reputation: 78750

enumerate yields (index + start, value) tuples for every value of an iterable. The optional start parameter is used as an offset value to compute the first element of the generated tuples:

>>> a = ['hi', 'stack', 'overflow']
>>> for x in enumerate(a, -4):
...     x
... 
(-4, 'hi') # 0 + (-4)
(-3, 'stack') # 1 + (-4)
(-2, 'overflow') # 2 + (-4)

If you want to skip elements of an iterable, but don't need that particular slice in memory (all you want to do is iteration), use itertools.islice:

>>> from itertools import islice
>>> for x in islice(a, 2, None):
...     x
... 
'overflow'

Of course, you could combine the two for great justice.

>>> for x in islice(enumerate(a), 0, 2):
...     x
... 
(0, 'hi')
(1, 'stack')

Upvotes: 2

Dan Getz
Dan Getz

Reputation: 9152

In enumerate(), start does not specify the starting index into the iterable. It specifies the starting value of the count. enumerate() iterates over the whole iterable, from the first (index 0) to the last element, regardless of the start parameter.

The first print statement in your loop prints mylist[0].dataFieldCheckType, just as it ought to. You're just hoping it would be mylist[1].dataFieldCheckType.

If you want to take all elements of the list starting at the second (index 1), just slice it:

mylist[1:]

And if you really do need the index, too, combine the slice with enumerate():

enumerate(mylist[1:], start=1)

Upvotes: 2

Related Questions