首页 > 解决方案 > 从给定索引数组的Python列表中提取子列表的最快方法

问题描述

我有任何类型的大型 Pythonl对象列表,还有另一个大型整数索引列表i(甚至NumPy数组)指向 list 中的某些元素l

问题是创建另一个列表的最快(最有效)方法是什么,该列表l2包含 的元素,l索引来自i.

最简单的方法是进行列表理解:

l2 = [l[si] for si in i]
# Use np.nditer(i) instead of i, for NumPy array case

但这是最快的方法吗?

列表理解是一个 Python 循环,所以对于大型列表可能会很慢,也许标准库中有一些内置的 Python 方法可以有效C地完成这个任务?或者也许NumPy有这样的方法可以通过 numpy 数组索引 Python 的列表?

也许标准 python 库中有一些简单而快速的函数可以对 NumPy 的np.take做同样的事情,就像下面的假想代码:

import listtools
l2 = listtools.take(l, indexes)

标签: pythonarrayslistnumpy

解决方案


operator.itemgetter通过使用支持批量查找,您可以获得较小的加速(在下面的示例中约为 25%) :

>>> import string
>>> import random
>>> import operator as op
>>> from timeit import timeit

# create random lists
>>> l = [random.choice([*string.ascii_letters,*range(100)]) for _ in range(1000000)]
>>> i = [random.randint(0,999999) for _ in range(300000)]

# timings
>>> timeit(lambda:[l[si] for si in i],number=100)
3.0997245000035036
>>> timeit(lambda:list(map(l.__getitem__,i)),number=100)
2.892384369013598
>>> timeit(lambda:list(op.itemgetter(*i)(l)),number=100)
2.1787672539940104

推荐阅读