知道其索引的多个列表元素

hoa*_*ran 203 python indexing element list python-3.x

我需要从给定列表中选择一些元素,知道它们的索引.假设我想创建一个新列表,其中包含索引为1,2,5的元素,来自给定列表[-2,1,5,3,8,5,6].我做的是:

a = [-2,1,5,3,8,5,6]
b = [1,2,5]
c = [ a[i] for i in b]
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法呢?像c = a [b]之类的东西?

Ter*_*ryA 192

你可以使用operator.itemgetter:

from operator import itemgetter 
a = [-2, 1, 5, 3, 8, 5, 6]
b = [1, 2, 5]
print(itemgetter(*b)(a))
# Result:
(1, 5, 5)
Run Code Online (Sandbox Code Playgroud)

或者你可以使用numpy:

import numpy as np
a = np.array([-2, 1, 5, 3, 8, 5, 6])
b = [1, 2, 5]
print(list(a[b]))
# Result:
[1, 5, 5]
Run Code Online (Sandbox Code Playgroud)

但实际上,您当前的解决方案很好.它可能是所有这些中最好的.

  • 提及'c = [a [i] for i in b]`的+1非常好.请注意,如果b少于2个元素,`itemgetter`解决方案将不会执行相同的操作. (30认同)
  • 补充说明,`a [b]`仅在`a`是numpy **数组时有效,即,您使用numpy函数创建它。 (2认同)
  • 我已经对非 numpy 选项进行了基准测试,并且 itemgetter 似乎是最快的,甚至比使用 Python 3.44 在括号内简单地输入所需索引稍快一些 (2认同)

fal*_*tru 42

备择方案:

>>> map(a.__getitem__, b)
[1, 5, 5]
Run Code Online (Sandbox Code Playgroud)
>>> import operator
>>> operator.itemgetter(*b)(a)
(1, 5, 5)
Run Code Online (Sandbox Code Playgroud)

  • 只需转换回列表:`list(map(a.__getitem__, b))` (2认同)

Don*_*the 8

比较提供的五个答案的执行时间的基本而不是非常广泛的测试:

def numpyIndexValues(a, b):
    na = np.array(a)
    nb = np.array(b)
    out = list(na[nb])
    return out

def mapIndexValues(a, b):
    out = map(a.__getitem__, b)
    return list(out)

def getIndexValues(a, b):
    out = operator.itemgetter(*b)(a)
    return out

def pythonLoopOverlap(a, b):
    c = [ a[i] for i in b]
    return c

multipleListItemValues = lambda searchList, ind: [searchList[i] for i in ind]
Run Code Online (Sandbox Code Playgroud)

使用以下输入:

a = range(0, 10000000)
b = range(500, 500000)
Run Code Online (Sandbox Code Playgroud)

简单的 python 循环是最快的,紧随其后的是 lambda 操作,mapIndexValues 和 getIndexValues 始终与 numpy 方法非常相似,在将列表转换为 numpy 数组后明显变慢。如果数据已经在 numpy 数组中,则删除 numpy.array 转换的 numpyIndexValues 方法是最快。

numpyIndexValues -> time:1.38940598 (when converted the lists to numpy arrays)
numpyIndexValues -> time:0.0193445 (using numpy array instead of python list as input, and conversion code removed)
mapIndexValues -> time:0.06477512099999999
getIndexValues -> time:0.06391049500000001
multipleListItemValues -> time:0.043773591
pythonLoopOverlap -> time:0.043021754999999995
Run Code Online (Sandbox Code Playgroud)


Bos*_*ova 8

另一个解决方案可以通过pandas Series:

import pandas as pd

a = pd.Series([-2, 1, 5, 3, 8, 5, 6])
b = [1, 2, 5]
c = a[b]
Run Code Online (Sandbox Code Playgroud)

然后,您可以根据需要将c转换回列表:

c = list(c)
Run Code Online (Sandbox Code Playgroud)