2014-10-10 3 views
0

목록의 일부 요소를 즉시 대체하려고합니다.목록의 지정된 색인을 변경하는 가장 좋은 방법

우리가이 목록이 있다고 가정 :

list = [1, 2, 3, 4, 5, 6] 
idx = [1, 3, 4] 
new = [100, 200, 300] 

내가 newlist의 요소 1, 3, 4를 대체합니다. 예를 들면 :

list[idx] = new 

때문에 최종 목록입니다 => 나는 당신이 matlab에이 방법을 사용할 수 있습니다 알고 있지만, 내가 파이썬에서 무엇을해야하는지 알고 싶어 [1, 100, 3, 200, 300, 6]

를?

참고 : 루프를 사용하는 것이 가능하다는 것을 알고 있습니다.


편집 : 나는 순수 파이썬 솔루션을 사용하고 싶습니다. 루프없이

답변

5

은 "파이썬"방법은 zip 사용하는 것입니다 :

for i, n in zip(idx, new): 
    L[i] = n 

파이썬 자체가 MATLAB 스타일의 배열 작업을 지원하지 않습니다 , 코딩 스타일에 관심이 있다면 numpy로 볼 수 있습니다 (@ abarnert의 대답 참조).

+2

또는 목록을 전혀 변형시키지 마십시오. 'd = dict (zip (idx, new))와 같은 것; L = [idx에 대한 d.get (idx, value), 열거 형 (L)에있는 값]'. – abarnert

+0

많은 경우에 새로운 목록이 더 적합 할 수 있지만 목록을 제자리에서 업데이트하는 것이 중요합니다. – alexis

+1

물론 그렇지만 가장 좋은 방법은 새 목록으로 작성한 다음 'L ='또는'L [:] ='...이 경우 사실 일 수도 있고 아닐 수도 있지만 그만한 가치가 있습니다. 초보자가 올바른 방법을 선택할 수 있도록 두 가지 방법을 모두 알고 있어야합니다. – abarnert

2
L = [1, 2, 3, 4, 5, 6] 
idx = [1, 3, 4] 
new = [100, 200, 300] 
for i in range(len(idx)): 
    L[idx[i]] = new[i] 

약간 느린 버전 :

L = [1, 2, 3, 4, 5, 6] 
idx = [1, 3, 4] 
new = [100, 200, 300] 
L = [num if i not in idx else new[i] for i,num in enumerate(L)] 
+1

먼저 'zip (idx, new)'대신'range (len (idx))'를 사용해야하는 이유는 무엇입니까? 또한, 두 번째 버전은 첫 번째 버전과 동일한 루프를 가지고 있으며 느리게 만드는 이유는 무엇입니까? – abarnert

+0

@abarnert : 두 번째 요소는 목록에서 O (n) 시간이 필요한 요소를 조회합니다. 따라서 경기 둔화. 'zip'은 제 첫 번째 루프보다 확실히 좋은 버전입니다. – inspectorG4dget

+0

아, 당신이 그렇게하고있는 것을 보지 못했습니다. 예, 느립니다. 하지만 아마도 꽤 빠를 수있는리스트 컴을 쉽게 작성할 수 있습니다 (이처럼 아주 작은 인풋에서는 느리지 만 누가 신경 써야합니까?). 필자는 아마도 C에서 true이기 때문에 일반적으로 새로운 목록을 작성하는 것보다 목록을 돌연변이시키는 것이 일반적으로 더 빠르다고 거짓으로 암시하는 답변이 너무 많아서 아마도 지나치게 조심 스러울 것입니다. 이는 종종 거짓이며 파이썬에서 더 자주 관련이없는 경우 일 수도 있습니다. 더 신중하게 읽지 않는 것에 대해 사과드립니다. – abarnert

2

Matlab과 같은 솔루션을 찾고 있으므로 여기에 실제로 NumPy을 사용해야 할 가능성이 있습니다. 당신이 그런 식으로 일을 할 경우에 실제로, 당신은 정확하게 당신이 원하는 코드를 작성할 수 있습니다 : 당신 matlab에 틱을 요소 현명한 연산자와 함수를 제공하는 외에

>>> import numpy as np 
>>> a = np.array([1, 2, 3, 4, 5, 6]) 
>>> idx = [1, 3, 4] 
>>> new = [100, 200, 300] 
>>> a[idx] = new 
>>> a 
array([ 1, 100, 3, 200, 300, 6]) 

을 NumPy와 또한 당신에게 편리한 다차원 배열을 제공하고, 거대한 상위 함수 라이브러리에 액세스 (특히 SciPy과 같은 보조 라이브러리를 포함하는 경우). 또한 일반적으로 6x 속도 및 0.25x 공간과 같은 성능상의 이점을 얻을 수 있습니다. 당신은 순수 파이썬 솔루션을 원하는 경우에


, 그것은 파이썬에서이 NumPy와의 많은 (또는 당신이 필요로하는만큼)를 구현하는 어려운 일이 아니다. 원하는 방식으로 emulates a container type 자신의 Array 클래스를 작성할 수 있습니다. 특히 a[idx] = newa.__setitem__(idx, new)입니다. 하나의 숫자와 슬라이스를 list과 같은 방식으로 다루기를 원하지만, list이 거부하는 다른 유형을 처리하는 것을 방해하지는 않습니다. 예를 들어 :

def __setitem__(self, idx, value): 
    if isinstance(idx, collections.abc.Iterable): 
     for i, v in zip(idx, value): 
      self.lst[i] = v 
    else: 
     self.lst[idx] = value 

(당신은 아마 오류 처리 idxvalue 서로 다른 길이를 가지고있는 경우에 약간을 추가 할 것입니다.첫 번째 원칙에서 최상의 규칙을 찾아 내거나 NumPy가하는 일을보고 무엇을하고 복사 할지를 결정함으로써 시작하십시오.

물론이 구현의 용기가 우연한 것은 아닙니다. 우리가하는 모든 작업이 논리를 마무리 짓기 때문에 알렉시스의 답변과 매우 흡사하게 코드가 작성되므로 필요할 때마다 작성해야합니다.

+0

Numpy는 좋은 라이브러리이며 전에 사용했습니다. 하지만 순수 파이썬 솔루션을 원합니다 :) – Mehdi1902

+0

@mehD : 글쎄, 당신은 항상 순수 파이썬에서 NumPy를 많이 쓸 수 있습니다. 실제로, 그것은 아주 사소한 것입니다. 내 업데이트 답변을 참조하십시오. – abarnert

관련 문제