What is faster for loop using enumerate or for loop using xrange in Python?
Asked Answered
A

3

9

What is faster, a for loop using enumerate or using xrange?

EDIT: I have tested, and I just see minimal differences.

Armistice answered 31/1, 2011 at 15:56 Comment(9)
They are not really interchangeable. What are you trying to do? Can you paste a code sample?Syllabogram
Why not test it (after determining that it matters)?Pulsometer
Wow, downvote heaven over here. Let's wait a little for an improved question. Perhaps the poster needs an answer as to why this question is difficult to answer... Let's be a little more welcoming to this new user and help him along on his first post.Samella
@Adam: They are if you want to have an index variable handy while you iterate.Promontory
@Marcelo that's what enumerate is for.Adopted
It's like asking "which gas will make my limousine go faster?" ... if you care about speed make the car lighter or get a different one.Outdated
@Josh: I don't know what point you are trying to make. My point was that both enumerate and xrange will provide an index as you iterate, and thus are somewhat interchangeable. Do you disagree with this?Promontory
@Jochen: High-octane gas will make some cars go faster, and using the right mixture is likely to be much cheaper that buying a different car. As for the question, I think it's perfectly reasonable to ask which is faster. Sometimes little things like this can make a big difference to performance-critical sections of code. In JavaScript, for instance, choosing the right looping construct can make a huge difference.Promontory
@Marcelo they are indeed somewhat interchangeable; I agree with this. I just think that enumerate is more Pythonic, easier to read, etc. But I think that, in the spree of voted comments, I lost the thread of the conversation, so my remark was a little off topic. Sorry. :)Adopted
N
10

Enumerate is slightly faster. Tested in Python 3:

>>>import pygame
>>>pygame.init()
>>>clock = pygame.time.Clock()
>>>a = list(range(100000))
>>>def do_with_range():
...    clock.tick()
...    k = 0
...    for i in range(len(a)):
...        k += a[i]
...    print(clock.tick())
>>>def do_with_enumerate():
...    clock.tick()
...    k = 0
...    for i, j in enumerate(a):
...        k += j
...    print(clock.tick())
>>>do_with_range()
23
>>>do_with_enumerate()
21

If a wouldn't be a list, but a generator, it would be significantly faster to use enumerate (74ms using range, 23ms using enumerate).

Nappy answered 31/1, 2011 at 16:24 Comment(7)
The question was actually asking about xrange, not rangeTeston
In Python 3 xrange got replaced by range and range is a generator now. This is also why i manually did list(range()). Thus, the results in Python 2 using xrange would be similar.Nappy
Okay, I tested it in Python 2 as well. For obscure reasons, Python 2 is a hell of a lot faster than Python 3, and the xrange and enumerate versions are of the same speed: 14ms. (Shouldn't one expect later versions of the language to be faster than previous ones? But well...).Nappy
And yet it's still faster to use a local that you increment rather than either of these methods. Enumerate is the Pythonic way, but unpacking tuples is slower than incrementing locals, and so it will probably always be slower (although only marginally so).Bullock
@Nick: Not to mention that the difference will be ridiculous, if noticeable at all, even a noticeable difference wouldn't justify the extra code and ugliness unless perhaps in an inner loop (which you should propably just write in Cython if speed is that important).Kutzer
@delnan: well, this actually comes into play using LLVM, where JIT optimizing += is quite different than JIT optimizing a function result being unpacked into two locals. Not that stackoverflow comments are the place to discuss the finer details of python efficiency.. :-) But suffice it to say that the global resource consumption of using enumerate() on a cluster can actually be a significant disadvantage compared to +=.Bullock
according to this page pythonfasterway.uni.me enumerate is faster than xrange. It is true. I tried it too.Gardol
S
6

You can use the timeit module in the standard library to compare both. The timeit.timeit() function used below takes a statement that it runs 1'000'000 times and returns the total time in seconds. In this test enumerate() is slightly slower.

>>> import timeit
>>> timeit.timeit('for i in xrange(100): a[i]', 'a = list(xrange(100))')
7.2920000553131104
>>> timeit.timeit('for i, o in enumerate(a): o', 'a = list(xrange(100))')
10.359999895095825
>>> timeit.timeit('for i in xrange(100): a[i] + 1', 'a = list(xrange(100))')
10.380000114440918
>>> timeit.timeit('for i, o in enumerate(a): o + 1', 'a = list(xrange(100))')
13.514999866485596
Shanklin answered 31/1, 2011 at 16:48 Comment(1)
in my tests enumerate is faster, python 3.6Reikoreilly
T
0

Mu.

For loops can use both enumerate and xrange at the same time, though it would be silly. The enumerate function adds an index so you can tell what the index of an item in your iterable is. The xrange function returns an iterable full of numbers. Use it when you want to do something a certain number of times, instead of for each element in an iterable.

Examples:

for idx, element in ['foo', 'bar', 'baz']:
    print idx, element

for idx in xrange(3):
    print idx
Tahitian answered 31/1, 2011 at 16:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.