From the right side

For lists, you can use slicing my_list[-10:]to get the last (before) 10items.

I want to do the same with itertools.islice. In this case, I have collections.deque.

Is there a more efficient way to do this than the following?

from collections import deque
import itertools
my_deque = deque()
my_list = list()
for i in range(100):
    my_deque.append(i)
    my_list.append(i)

And then we chop:

start = max(0, len(my_deque) - 10)
for i in list(itertools.islice(my_deque, start, None)):
    pass

My timings:

deque: 1,000,000 cycles, best 3: 962 nsper cycle

cut list: 10,000,000 cycles, best 3: 95.9 nsper cycle

+4
source share
1 answer

As you found out, there is no way to cut a collections.deque. But it supports rotation, which can be used in this case:

last_n = 10
my_deque.rotate(last_n)
for i in itertools.islice(my_deque, last_n):
    pass

itertools.islice , , stop. , , list deque s. islice deque. rotate, islice 10 .

, , , :

from collections import deque
import itertools
my_deque = deque(range(10000))
my_list = list(range(10000))

:

%%timeit

my_deque.rotate(10)
for i in itertools.islice(my_deque, 10):
    pass
my_deque.rotate(-10)  # so the next timing operates on the orginal deque again

2,76 ± 41,6 ( ± 7 , 100000 )

%%timeit

start = max(0, len(my_deque) - 10)
for i in itertools.islice(my_deque, start, None):
    pass

136 ± 8,08 ( ± 7 , 10000 )

%%timeit

start = max(0, len(my_list) - 10)
for i in itertools.islice(my_list, start, None):
    pass

119 ± 1,64 ( ± 7 , 10000 )

%timeit my_list[-10:]

434 ns ± 12,5 ( ± 7 , 1000000 )

, ( ~ 5 ), (~ 50 ), islice.

+1

Source: https://habr.com/ru/post/1683167/


All Articles