2016-11-01 6 views
-1

자, 다시 시도해 보겠습니다. 1 세트의 데이터가 있습니다. 나는 2 개의 복사본을 만들고 다른 열을 기반으로 내림차순으로 복사본을 정렬하려고합니다. 그런 다음 각 열의 누적 합계를 구합니다. 다음 코드를 실행할 때 print (setA [x] [2])를 호출하는 두 인스턴스에 대해 다른 결과를 얻습니다.for 루프로 합계 할 때 다른 결과를주는 파이썬 누적 합계

5 
6 
8 
6 

을하지만 대신

5 
6 
5 
6 

을 미치지 :

set = [[2,2,0],[1,3,0],[3,1,0]] 

def getkey_setA (item): 
    return item[0] 
setA = sorted(set, key=getkey_setA, reverse=True) 

def getkey_setB (item): 
    return item[1] 
setB = sorted(set, key=getkey_setB, reverse=True) 

setA[0][2] = setA[0][0] 
setB[0][2] = setB[0][1] 

for x in range(1, 3): 
    setA[x][2] = setA[x-1][2] + setA[x][0] 
    print(setA[x][2]) 

for x in range(1, 3): 
    setB[x][2] = setB[x-1][2] + setB[x][1] 

for x in range(1, 3): 
    print (setA[x][2]) 

이 생산하고 있습니다.

+1

목록에 * 공유 참조 *가있는 것 같습니다 (아마도 목록을 복사하지 않았을 것입니다.) (http://stackoverflow.com/questions/2612802/how-to-clone-or-copy -목록))? 그러나 [MCVE]가 없다면 우리는 도울 수 없습니다. –

+0

Gotcha. 위의 편집 된 예를 참조하십시오. – Jellybeard

+0

그리고 생성되는 출력은 무엇이며 예상 출력은 무엇입니까? –

답변

1

sorted()얕은 순열을 만듭니다. 이것은 당신의중첩 된 목록은, 그들이 단순히 참조하는 복사되지 않음을 의미 :

>>> set = [[2,2,0],[1,3,0],[3,1,0]] 
>>> setA = sorted(set, key=getkey_setA, reverse=True) 
>>> setB = sorted(set, key=getkey_setB, reverse=True) 
>>> setA[0] is set[2] 
True 
>>> setB[2] is set[2] 
True 
>>> setA[0] is setB[2] 
True 

그래서 set의 마지막 요소는 setA[0]setB[2]와 정확히 같은 객체입니다. 이러한 참조 중 하나를 만들기 변경 사항은 다른 사람들에 반영됩니다 :

>>> setA[0][2] 
0 
>>> setA[0][2] = 42 
>>> setB[2] 
[3, 1, 42] 
>>> set[2] 
[3, 1, 42] 

이다 (당신이 당신의 분류 setAsetB 목록을 생성되는)을 set 객체가 이 코드를 실행 한 후 변경 이유 :

>>> set 
[[2, 2, 8], [1, 3, 6], [3, 1, 9]] 

중첩 목록의 적절한 복사본을 만들어야합니다. 정렬 할 때 당신은 목록 개체의 순환 사본을 만들 수 copy.deepcopy() function을 사용할 수 있습니다, 또는 당신은 발전기 표현을 사용할 수 있습니다

setA = sorted((subl[:] for subl in set), key=getkey_setA, reverse=True) 
setB = sorted((subl[:] for subl in set), key=getkey_setB, reverse=True) 

이 얕게 복사 중첩 된 목록을; 이러한 중첩 된 목록에는 불변 개체 만 포함되어 있기 때문에 괜찮습니다.

+0

감사합니다. 알겠습니다. 또한 1) setA에 대한 데이터 정렬, 2) 출력 파일에 내 결과 기록, 3) B 세트에 대한 데이터 정렬, 4) 결과 파일에 내 결과 기록. 이 방법으로 실제 사본에는 수백만 개의 항목이있는 일련의 사본이 여러 개 생성되는 것을 피할 수 있습니다. – Jellybeard

+0

@ Jellybeard : 누적 된 데이터를 대신 생성하려면 ['itertools.accumulate()'] (https://docs.python.org/3/library/itertools.html#itertools.accumulate)를 사용 하시겠습니까? 3 번째 요소를 변수로 사용하는 것을 피하고 주문 공유를 계속할 수 있습니다. 또는 더 나은 방법은'pandas' 프로젝트를 사용하여 정렬과 누적을 수행하는 것입니다.이 작업에서는 훨씬 더 효율적입니다. –