[python] 색인을 알고있는 목록의 여러 요소에 액세스

주어진 목록에서 색인을 알고 일부 요소를 선택해야합니다. 주어진 목록 [-2, 1, 5, 3, 8, 5, 6]에서 색인 1, 2, 5를 가진 요소를 포함하는 새 목록을 만들고 싶다고합시다. 내가 한 일은 :

a = [-2,1,5,3,8,5,6]
b = [1,2,5]
c = [ a[i] for i in b]

더 좋은 방법이 있습니까? c = a [b]와 같은 것?



답변

당신은 사용할 수 있습니다 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)

또는 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]

그러나 실제로는 현재 솔루션이 좋습니다. 아마도 그들 중 가장 끔찍할 것입니다.


답변

대안 :

>>> map(a.__getitem__, b)
[1, 5, 5]

>>> import operator
>>> operator.itemgetter(*b)(a)
(1, 5, 5)


답변

또 다른 해결책은 pandas Series를 통한 것일 수 있습니다.

import pandas as pd

a = pd.Series([-2, 1, 5, 3, 8, 5, 6])
b = [1, 2, 5]
c = a[b]

원하는 경우 c를 목록으로 다시 변환 할 수 있습니다.

c = list(c)


답변

제공된 다섯 가지 답변의 실행 시간을 비교하는 기본적이고 광범위하지 않은 테스트 :

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]

다음 입력을 사용하여 :

a = range(0, 10000000)
b = range(500, 500000)

간단한 파이썬 루프는 람다 연산이 가장 빠르며 두 번째로 빠르며 mapIndexValues ​​및 getIndexValues는 목록을 numpy 배열로 변환 한 후 numpy 메소드와 상당히 유사합니다. 가장 빠릅니다.

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


답변

나는 이것이 이미 고려되었다고 확신합니다 : b의 인덱스의 양이 작고 일정하다면 다음과 같은 결과를 쓸 수 있습니다.

c = [a[b[0]]] + [a[b[1]]] + [a[b[2]]]

또는 지수 자체가 상 수면 더 간단합니다 …

c = [a[1]] + [a[2]] + [a[5]]

또는 연속 인덱스 범위가있는 경우 …

c = a[1:3] + [a[5]]


답변

더 간단한 방법은 다음과 같습니다.

a = [-2,1,5,3,8,5,6]
b = [1,2,5]
c = [e for i, e in enumerate(a) if i in b]


답변

내 대답은 numpy 또는 python 컬렉션을 사용하지 않습니다.

요소를 찾는 간단한 방법은 다음과 같습니다.

a = [-2, 1, 5, 3, 8, 5, 6]
b = [1, 2, 5]
c = [i for i in a if i in b]

단점 :이 방법은 더 큰 목록에서는 작동하지 않을 수 있습니다. 더 큰 목록에는 numpy를 사용하는 것이 좋습니다.