Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python loop with enumerate by 2

I'm not 100% sure how to pose the question's title, but what I want to do is simple. I want to loop over a list using the enumerate function in Python, but I want to know if it's possible to do it by 2, something I would do without enumerate, like this:

numbers = ['One', 'Two', 'Three', 'Four', 'Five']

i = 0
for number in numbers:
    print(i, number)
    i += 2

Is it possible to do it using enumerate function (Pythonic way), or I should do it like in the example?

like image 715
Andrés Orozco Avatar asked Mar 11 '23 21:03

Andrés Orozco


2 Answers

Just multiply the enumerate() output by two:

for i, number in enumerate(numbers):
    print(i * 2, number)

This is essentially what the range() object does in Python 3; calculate the number for any given index. Since your series starts at 0, all you have to do is multiply i by your step size.

Another method would be to zip() a itertools.count() object along:

from itertools import count
try:
    # Python 2, use the iterator version of zip
    from future_builtins import zip
except ImportError:
    # Python 3
    pass

for i, number in zip(count(step=2), numbers):
    print(i, number)

Demo in Python 3:

>>> from itertools import count
>>> numbers = ['One', 'Two', 'Three', 'Four', 'Five']
>>> for i, number in enumerate(numbers):
...     print(i * 2, number)
...
0 One
2 Two
4 Three
6 Four
8 Five
>>> for i, number in zip(count(step=2), numbers):
...     print(i, number)
...
0 One
2 Two
4 Three
6 Four
8 Five
like image 141
Martijn Pieters Avatar answered Mar 20 '23 22:03

Martijn Pieters


A little bit of profiling of Martijn's two Python 3 accepted solutions (tested on 3.7.4):

enumerate():

python -m timeit -s "numbers = ['One', 'Two', 'Three', 'Four', 'Five']" "for i, n in enumerate(numbers): i*2"
500000 loops, best of 5: 403 nsec per loop

zip(count(...), ...):

python -m timeit -s "from itertools import count; numbers = ['One', 'Two', 'Three', 'Four', 'Five']" "for i, n in zip(count(step=2), numbers): i"
500000 loops, best of 5: 690 nsec per loop

zip/count method is 1.7x slower.

enumerate(...) & len(numbers) == 5000:

python -m timeit -s "numbers = ['One', 'Two', 'Three', 'Four', 'Five'] * 1000" "for i, n in enumerate(numbers): i*2"
1000 loops, best of 5: 324 usec per loop

zip(count(...), ...) & len(numbers) == 5000:

python -m timeit -s "from itertools import count; numbers = ['One', 'Two', 'Three', 'Four', 'Five'] * 1000" "for i, n in zip(count(step=2), numbers): i"
1000 loops, best of 5: 219 usec per loop

With list length of 5000, zip/count method is a third faster, my guess is that the overhead of creating both the zip and count objects makes that method slower for small lists but that is eventually outweighed by having to perform i * 2 so often in with a large number of iterations.

And of course, while the proportions look significant, in the first case we are talking a difference of 0.000000287 seconds, and in the large list case, 0.000105 seconds difference.

like image 23
SuperShoot Avatar answered Mar 20 '23 23:03

SuperShoot