如何有效地访问另一个可迭代的Python可迭代索引

Ped*_*dro 2 python arrays loops numpy list

我有一个列表X和一个列表Y,其中有一些洗牌索引.

X = ['a', 'b', 'c', 'd','e']
Y = [ 1 ,  3 ,  4 ,  0 , 2 ]
Run Code Online (Sandbox Code Playgroud)

我想有一个新的列表Z,使得

Z = [ X[i] for i in Y ] = ['b', 'd', 'e', 'a', 'c']
Run Code Online (Sandbox Code Playgroud)

问题是我必须多次这样做,因为这么大arrays.有什么比循环列表更有效的方法?

注意: numpy解决方案是相关的!

ran*_*mir 5

由于operator.itemgetter接受多个索引,一个解决方案是:

>>> import operator
>>> operator.itemgetter(*Y)(X)
('b', 'd', 'e', 'a', 'c')
Run Code Online (Sandbox Code Playgroud)

高效的(如评论中所述)将是via numpy的数组索引:

np.array(X)[Y]
Run Code Online (Sandbox Code Playgroud)

只有XY被转换成numpy.array一次(使用提前),并多次使用.


性能测试

从元素列表1k(Y)索引元素1M(X).

# setup
import random
import numpy as np
X = [random.randint(0,100) for i in range(1000000)]
Y = [random.randint(0,1000000) for i in range(1000)]
Run Code Online (Sandbox Code Playgroud)

1)列表理解~34μs

%timeit [X[i] for i in Y]
10000 loops, best of 3: 34 µs per loop
Run Code Online (Sandbox Code Playgroud)

2)itemgetter~16.6μs

%timeit operator.itemgetter(*Y)(X)
100000 loops, best of 3: 16.6 µs per loop
Run Code Online (Sandbox Code Playgroud)

3)numpy,在飞行时转换的阵列~31.6ms⇒最慢

%timeit np.array(X)[Y]
10 loops, best of 3: 31.6 ms per loop
Run Code Online (Sandbox Code Playgroud)

4)numpy,阵列预转换~1.72μs⇒最快

x = np.array(X)
y = np.array(Y)
%timeit x[y]
1000000 loops, best of 3: 1.72 µs per loop
Run Code Online (Sandbox Code Playgroud)