views:

415

answers:

1

There is a nice class Enum from enum, but it only works for strings. I'm currently using:

    for index in range(len(objects)):
        # do something with index and objects[index]

I guess it's not the optimal solution due to the premature use of len. How is it possible to do it more efficiently?

+9  A: 

Here is the pythonic way to write this loop:

for index, obj in enumerate(objects):
  # Use index, obj.

enumerate works on any sequence regardless of the types of its elements. It is a builtin function.

Edit:

After running some timeit tests using Python 2.5, I found enumerate to be slightly slower:

>>> timeit.Timer('for i in xrange(len(seq)): x = i + seq[i]', 'seq = range(100)').timeit()
10.322299003601074
>>> timeit.Timer('for i, e in enumerate(seq): x = i + e', 'seq = range(100)').timeit()
11.850601196289062
Ayman Hourieh
Is it more efficient?
Bastien Léonard
@Bastien - After some timeit tests, I found `enumerate` to be slightly slower than the code in the question. I will update my answer.
Ayman Hourieh
in py3k results are quite opposite: range version is 3 times slower than enumerate version.
SilentGhost
@SilentGhost - you probably forgot to change `range(100)` to `list(range(100))`. enumerate() is _slightly_ faster on python 3.0 but only by ~4%, not 3x.
Ivan Baldin
@SilentGhost - Thanks for testing. I ran my tests in Python 2.5 (edited the answer to reflect this). I don't have access to Python 3.0 at the moment so I cannot try.
Ayman Hourieh
while overhead of accessing an item of a list is lower than that of a range, the difference could be anything up to 50%, depending on whether original sequence is ordered.
SilentGhost