Getting a sublist of a Python list, with the given indices?
You can use list comprehension to get that list:
c = [a[index] for index in b]
print c
This is equivalent to:
c= []
for index in b:
c.append(a[index])
print c
Output:
[0,2,4,5]
Note:
Remember that some_list[index]
is the notation used to access to an element of a list
in a specific index.
Something different...
>>> a = range(7)
>>> b = [0,2,4,5]
>>> import operator
>>> operator.itemgetter(*b)(a)
(0, 2, 4, 5)
The itemgetter
function takes one or more keys as arguments, and returns a function which will return the items at the given keys in its argument. So in the above, we create a function which will return the items at index 0, index 2, index 4, and index 5, then apply that function to a
.
It appears to be quite a bit faster than the equivalent list comprehension
In [1]: import operator
In [2]: a = range(7)
In [3]: b = [0,2,4,5]
In [4]: %timeit operator.itemgetter(*b)(a)
1000000 loops, best of 3: 388 ns per loop
In [5]: %timeit [ a[i] for i in b ]
1000000 loops, best of 3: 415 ns per loop
In [6]: f = operator.itemgetter(*b)
In [7]: %timeit f(a)
10000000 loops, best of 3: 183 ns per loop
As for why itemgetter
is faster, the comprehension has to execute extra Python byte codes.
In [3]: def f(a,b): return [a[i] for i in b]
In [4]: def g(a,b): return operator.itemgetter(*b)(a)
In [5]: dis.dis(f)
1 0 BUILD_LIST 0
3 LOAD_FAST 1 (b)
6 GET_ITER
>> 7 FOR_ITER 16 (to 26)
10 STORE_FAST 2 (i)
13 LOAD_FAST 0 (a)
16 LOAD_FAST 2 (i)
19 BINARY_SUBSCR
20 LIST_APPEND 2
23 JUMP_ABSOLUTE 7
>> 26 RETURN_VALUE
While itemgetter
is a single call implemented in C:
In [6]: dis.dis(g)
1 0 LOAD_GLOBAL 0 (operator)
3 LOAD_ATTR 1 (itemgetter)
6 LOAD_FAST 1 (b)
9 CALL_FUNCTION_VAR 0
12 LOAD_FAST 0 (a)
15 CALL_FUNCTION 1
18 RETURN_VALUE