Reputation: 2553
Say we have a list of integers from 0 to 1000:
[0, 1, 2, 3, ..., 997, 998, 999]
How do I get a new list containing the first and every subsequent 10th item?
[0, 10, 20, 30, ..., 990]
I can do this using a for loop, but is there a neater way, perhaps even in one line of code?
Upvotes: 246
Views: 380841
Reputation: 85045
>>> xs = list(range(165))
>>> xs[0::10]
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
Note that this is around 100 times faster than looping and checking a modulus for each element:
$ python -m timeit -s "xs = list(range(1000))" "[x for i, x in enumerate(xs) if i % 10 == 0]"
500 loops, best of 5: 476 usec per loop
$ python -m timeit -s "xs = list(range(1000))" "xs[0::10]"
100000 loops, best of 5: 3.32 usec per loop
Upvotes: 407
Reputation: 9391
Use range(start, end, step)
li = list(range(0, 1000, 10))
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90 ... 990]
Or, if you have a list use slice: From manual: s[i:j:k] slice of s from i to j with step k
yourlist = [0, ... ,10 ...]
sub = yourlist[::10] # same as yourlist[0:100:10]
>>> sub
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
Upvotes: 36
Reputation: 33200
source_list[::10]
is the most obvious, but this doesn't work for any iterable and is not memory efficient for large lists.itertools.islice(source_sequence, 0, None, 10)
works for any iterable and is memory-efficient, but probably is not the fastest solution for large list and big step.(source_list[i] for i in xrange(0, len(source_list), 10))
Upvotes: 75
Reputation: 4468
List comprehensions are exactly made for that:
smaller_list = [x for x in range(100001) if x % 10 == 0]
You can get more info about them in the python official documentation: http://docs.python.org/tutorial/datastructures.html#list-comprehensions
Upvotes: -10
Reputation: 43120
You can use the slice operator like this:
l = [1,2,3,4,5]
l2 = l[::2] # get subsequent 2nd item
Upvotes: 33
Reputation: 76992
Why not just use a step parameter of range function as well to get:
l = range(0, 1000, 10)
For comparison, on my machine:
H:\>python -m timeit -s "l = range(1000)" "l1 = [x for x in l if x % 10 == 0]"
10000 loops, best of 3: 90.8 usec per loop
H:\>python -m timeit -s "l = range(1000)" "l1 = l[0::10]"
1000000 loops, best of 3: 0.861 usec per loop
H:\>python -m timeit -s "l = range(0, 1000, 10)"
100000000 loops, best of 3: 0.0172 usec per loop
Upvotes: 4
Reputation: 63729
Here is a better implementation of an "every 10th item" list comprehension, that does not use the list contents as part of the membership test:
>>> l = range(165)
>>> [ item for i,item in enumerate(l) if i%10==0 ]
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
>>> l = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
>>> [ item for i,item in enumerate(l) if i%10==0 ]
['A', 'K', 'U']
But this is still far slower than just using list slicing.
Upvotes: 1
Reputation:
existing_list = range(0, 1001)
filtered_list = [i for i in existing_list if i % 10 == 0]
Upvotes: 3
Reputation: 131600
newlist = oldlist[::10]
This picks out every 10th element of the list.
Upvotes: 13