Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manual slicing of a list using their indices, Python

Minimal example

I have a list a = [10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,....,]

I want to get a new list new_list = [40,50,60,100,110,120,...], i.e. append fourth, fifth and sixth value, skip next three, append next three and so on.

My idea is to create a list called index:

index = [3,4,5,9,10,11,...] new_list = [a[i] for i in index] # This should give me what I want

but how do I create the list index ? I know np.arange has the step option, but that is only for spacing between values.

like image 416
Srivatsan Avatar asked Jan 02 '23 17:01

Srivatsan


2 Answers

Here's one way -

[a[i] for i in range(len(a)) if i%6>=3]

Sample run -

In [49]: a = [10,20,30,40,50,60,70,80,90,100,110,120,130,140,150]

In [50]: [a[i] for i in range(len(a)) if i%6>=3]
Out[50]: [40, 50, 60, 100, 110, 120]
like image 177
Divakar Avatar answered Jan 10 '23 01:01

Divakar


Here's an improved and faster version using Python built-in function enumerate building up on Divakar's nice logic.

In [4]: lst = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150]
In [6]: [item for idx, item in enumerate(lst) if idx%6 >= 3]
Out[6]: [40, 50, 60, 100, 110, 120]

why is this version better & preferable?

In [10]: lst = range(10, 100000, 10)       

In [11]: %timeit [lst[idx] for idx in range(len(lst)) if idx % 6 >= 3]
1.1 ms ± 22.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [12]: %timeit [item for idx, item in enumerate(lst) if idx % 6 >= 3]
788 µs ± 8.67 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

That's more than 300 microseconds gain! Furthermore, enumerate() is more straightforward and intuitive (c.f. loop like a native)

like image 40
kmario23 Avatar answered Jan 10 '23 01:01

kmario23