Use the itertools.islice() object to limit iteration to every n-th object, this is at least twice as fast as any other proposed solution:
from itertools import islice
n = 5
for ob in islice(iterable, None, None, n):
print(ob)
The above efficiently produces every 5th object, starting at the first:
>>> from itertools import islice
>>> from string import ascii_uppercase as iterable
>>> n = 5
>>> for ob in islice(iterable, None, None, n):
... print(ob)
...
A
F
K
P
U
Z
Replace the first None with n - 1 if you want to skip to the nth object as the first to use:
>>> for ob in islice(iterable, n - 1, None, n):
... print(ob)
...
E
J
O
T
Y
No copy of the input sequence is created to achieve this, so no additional memory or time is needed to produce the results. And taking every n-th object is done more efficiently than a % modulus test against an index from enumerate() could ever make it, or using range() to generate an index. That's because no further Python bytecode steps are needed to make those extra tests or index operations.
If you also needed to have the index of the items selected this way, add enumerate() back in by wrapping the iterable:
>>> for i, ob in islice(enumerate(iterable), n - 1, None, n):
... print(i, ob)
...
4 E
9 J
14 O
19 T
24 Y
islice() beats any other solution hands-down if you need speed:
>>> from timeit import timeit
>>> from itertools import islice
>>> import random
>>> testdata = [random.randrange(1000) for _ in range(1000000)] # 1 million random numbers
>>> def islice_loop(it):
... for ob in islice(it, None, None, 5): pass
...
>>> def range_loop(it):
... for i in range(0, len(it), 5): ob = it[i]
...
>>> def slice_loop(it):
... for ob in it[::5]: pass
...
>>> def enumerate_test_loop(it):
... for i, ob in enumerate(it):
... if i % 5 == 0: pass
...
>>> def enumerate_list_slice_loop(it):
... for i, ob in list(enumerate(it))[::5]: pass
...
>>> timeit('tf(t)', 'from __main__ import testdata as t, islice_loop as tf', number=1000)
4.194277995004086
>>> timeit('tf(t)', 'from __main__ import testdata as t, range_loop as tf', number=1000)
11.904250939987833
>>> timeit('tf(t)', 'from __main__ import testdata as t, slice_loop as tf', number=1000)
8.32347785399179
>>> timeit('tf(t)', 'from __main__ import testdata as t, enumerate_list_slice_loop as tf', number=1000)
198.1711291699903
So, for 1 million inputs, and 1000 tests, the enumerate() approach took sixteen times as much time as the islice() version, and the list(enumerate(...))[::n] copy-and-slice operation took almost 3 minutes to run the 1000 tests, clocking in at almost fifty times slower execution time. Don't ever use that option!
for i, item in enumerate(n):.iis your counter.enumerate()is basically used to iterate over items of a list as well as to have an access to its index.for index, value in enumerate(n[::nth]): print(index, value)(but it will cost memory, because it's a copy)