2

次のスクリプトで問題が発生しました。個別に変更できるように、次のリストのコピーを3つ作成する必要があります。ただし、同じリストのクローンを3つ作成しているようで、1つを変更すると、それらすべてが変更されます。関数は次のとおりです。

def calculateProportions(strategies,proportions):
   import itertools
   combinations = []
   columns = list(itertools.product(strategies,repeat=3))
   for i in range(0,len(columns)):
      columns[i] = list(columns[i])
   for n in range(0,len(strategies)):
      combinations.append(columns[:])
   combinations[0][0][0] = "THIS SHOULD ONLY BE IN ONE PLACE"
   print combinations 
strategies = [[0,0],[0,50],[50,50]]
calculateProportions(strategies,[])

これを実行すると、文字列「THIS SHOULD BE IN ONE PLACE」が3回表示されることに注意してください(位置[0] [0] [0]、[1] [0] [0]、および[2] [0] ] [0]、一度ではありません。これは、リストが複製されるのではなく、一緒にエイリアス化されているためと思われます。ただし、明示的に複製しました。

私はこの1時間、頭をテーブルにぶつけて過ごしました。あなたの提案した解決策は大歓迎です!

4

5 に答える 5

4

を複製するときは、浅いコピーのみを実行します。columnsつまり、リストは複製されますが、その項目は複製されないため、 と の両方で同じ項目参照が使用されcombinationsますcolumns

copy.deepcopy()関数を使用して、オブジェクトのディープ コピーを実行できます。

def calculateProportions(strategies,proportions):
    import copy
    import itertools
    combinations = []
    columns = list(itertools.product(strategies, repeat=3))
    for i in range(0, len(columns)):
        columns[i] = list(columns[i])
    for n in range(0, len(strategies)):
        combinations.append(copy.deepcopy(columns))

または、より単純に、リスト内包表記:

def calculateProportions(strategies,proportions):
    import itertools
    combinations = []
    columns = list(itertools.product(strategies, repeat=3))
    for i in range(0, len(columns)):
        columns[i] = list(columns[i])
    for n in range(0, len(strategies)):
        combinations.append([item[:] for item in columns])
于 2010-12-08T08:58:09.727 に答える
0

ディープ コピーを修正しようとする代わりに、ネストされたリスト内包表記を使用して目的のデータを作成するだけです。これにより、最終データの醜い手動の「蓄積」も回避されます。

def calculateProportions(strategies, proportions):
  import itertools
  combinations = [
    [list(x) for x in itertools.product(strategies, repeat = 3)]
    for strategy in strategies
  ]
  combinations[0][0][0] = "THIS SHOULD ONLY BE IN ONE PLACE"
  print combinations 
于 2010-12-08T09:17:55.133 に答える
0
>>> import copy
>>> help(copy)

一番最初の行には、関数copydeepcopy. これらは、浅いコピーと深いコピーに対応しています。詳細については、http://en.wikipedia.org/wiki/Object_copyを参照してください。

于 2010-12-08T08:52:22.300 に答える
0

次のようなリストのコピーを取得しても、リストに含まれる要素のコピーは作成さlist[:]れませ (つまり、ディープコピーではなくフラットコピーです)。次のコード例は、これを示しています。

>>> n1 = [1, 2]
>>> n2 = [3, 4]
>>> l1 = [n1, n2]
>>> l2 = l1[:]
>>> l2[0] = "was n1" # change in l1 only
>>> l1
[[1, 2], [3, 4]]
>>> l2
['was n1', [3, 4]]
>>> l2[1][0] = "was 3 in n2" # affects both l1 and l2
>>> l1
[[1, 2], ['was 3 in n2', 4]]
>>> l2
['was n1', ['was 3 in n2', 4]]

uridtko が示唆しているように、copyモジュールがあなたの場合に役立つかもしれません。

于 2010-12-08T08:57:18.733 に答える
0

あなたが書くとき

l = 連想リスト[:]

あなたは浅いコピーをしています。つまり、リストは異なりますが、2 つのリストは同じオブジェクトを指しています。したがって、リストの 1 つの要素を変更すると、他のリストの要素も変更されます。

ディープコピーを作成する必要があります。リストとリスト内のすべてのオブジェクトをコピーします。

import copy
copy.deepcopy()
于 2010-12-08T08:57:57.500 に答える