2016-11-01 3 views
-1

これをもう一度試してみましょう。私は1セットのデータを持っています。私は2つのコピーを作成し、次に異なる列に基づいて降順でコピーをソートしたい。次に、それぞれの列の累積合計を求めたいと思います。次のコードを実行すると、print(setA [x] [2])を呼び出す2つのインスタンスに対して異なる結果が得られます。forループで合計すると異なる結果を与えるPythonの累積合計

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]) 

これが生成します。

5 
6 
8 
6 

を私はそれが代わりに

5 
6 
5 
6 

を生成すると予想。

+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]とまったく同じオブジェクトです。これらの参照のいずれかの設定は変更他人に反映されます。

:(あなたのソートsetAsetBリストを作成し、そこから)setオブジェクトがあなたのコードを実行した後に変更である理由

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

です

>>> 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'プロジェクトを使用してソートと蓄積を行うことです。この作業ではもっと効率的です。 –