주어진 목록에서 색인을 알고 일부 요소를 선택해야합니다. 주어진 목록 [-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]와 같은 것?
lambda
함수에 싸여 있습니다.
주어진 목록에서 색인을 알고 일부 요소를 선택해야합니다. 주어진 목록 [-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]와 같은 것?
lambda
함수에 싸여 있습니다.
답변:
당신은 사용할 수 있습니다 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]
그러나 실제로는 현재 솔루션이 좋습니다. 아마도 그들 중 가장 끔찍할 것입니다.
c = [a[i] for i in b]
완벽하게 언급하면 +1입니다 . 있습니다 itemgetter
B 미만이 개 요소가있는 경우 해결책은 같은 일을하지 않습니다.
a[b]
작동 만 할 때 a
A는 NumPy와 배열, 당신은 NumPy와 기능을 만들 즉.
대안 :
>>> map(a.__getitem__, b)
[1, 5, 5]
>>> import operator
>>> operator.itemgetter(*b)(a)
(1, 5, 5)
build-in
함수 를 사용하기 때문에 좋습니다
__getitem__
비교할 수없는 것처럼 보입니다. 예를 들어 항목 유형을 매핑하는 방법은 무엇입니까? map(type(a.__getitem__), b)
lambda x: type(a.__getitem__(x)), b
. 이 경우 사용 [..]
이 더 간결합니다.lambda x: type(a[x]), b
제공된 다섯 가지 답변의 실행 시간을 비교하는 기본적이고 광범위하지 않은 테스트 :
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
numpyIndexValues
이후 일을하지 않는 a
, b
유형입니다 range
. 난 당신이 변환에, 표준 추측하고 a
, b
에 numpy.ndarrays
먼저?
나는 이것이 이미 고려되었다고 확신합니다 : 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] + [b] = [a, 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를 사용하는 것이 좋습니다.
a
. [a[i] for i in b]
a
다른 5 개가 있다면 ?
[a[i] if i<len(a) else None for i in b]
예제와 같이 목록이 작고 색인이 변경되지 않는 경우 시퀀스 풀림 을 사용하는 것이 가장 좋습니다 .
_,a1,a2,_,_,a3,_ = a
성능이 훨씬 우수하며 한 줄의 코드를 저장할 수도 있습니다.
%timeit _,a1,b1,_,_,c1,_ = a
10000000 loops, best of 3: 154 ns per loop
%timeit itemgetter(*b)(a)
1000000 loops, best of 3: 753 ns per loop
%timeit [ a[i] for i in b]
1000000 loops, best of 3: 777 ns per loop
%timeit map(a.__getitem__, b)
1000000 loops, best of 3: 1.42 µs per loop
파이 토닉 방식 :
c = [x for x in a if a.index(x) in b]
O(n)
솔루션으로 솔루션 을 전환했습니다 O(n^2)
. 또한 목록이 경우 물체가 흐리거나 부분적인 평등, 예를 들어 것입니다 포함 된 경우 실패합니다 그 방법을주의하는 것이 좋습니다 a
포함 float('nan')
,이 것 항상 인상 ValueError
.