克隆列表似乎充当别名,即使明确声明为克隆

发布于 2024-10-06 13:41:14 字数 731 浏览 4 评论 0原文

我在使用以下脚本时遇到一些问题。应将以下列表复制 3 份,以便可以独立修改。然而,它似乎创建了同一个列表的 3 个克隆,当你修改一个列表时,你就会修改它们全部。这是该函数:

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],这似乎是因为这些列表是别名在一起而不是克隆的,但是我在

最后一个小时里一直在研究您的建议。非常感谢解决方案!

I am having some trouble with the following script. It should make 3 copies of the following list so that they can be modified independently. However, it seems to be creating 3 clones of the same list, and when you modify one you modify them all. Here is the function:

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

Notice how, when you run this, you see the string "THIS SHOULD BE IN ONE PLACE" 3 times (position [0][0][0],[1][0][0], and [2][0][0], not once. This appears to be because the lists are aliased together rather than cloned. However I explicitly cloned it.

I have spent the last hour banging my head into the table on this. Your suggested solutions are much appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

<逆流佳人身旁 2024-10-13 13:41:14

当您克隆时,您仅执行浅拷贝 ,即列表被克隆,但其项目未被克隆,因此在组合中使用相同的项目引用。

您可以使用 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])

You're only performing a shallow copy when you clone columns, i.e. the list is cloned but its items are not, so the same item references are used in both combinations and columns.

You can use the copy.deepcopy() function to perform a deep copy of the object:

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

Or, more simply, a list comprehension:

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])
め七分饶幸 2024-10-13 13:41:14

获取像 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]]

正如 ulidtko 所建议的, copy 模块可能会帮助您案件。

Getting a copy of a list like list[:] does not create copies of the elements contained in the list (i.e. it is a flat copy, not a deep copy). The following example code illustrates this:

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

As suggested by ulidtko, the copy module might help in your case.

幻想少年梦 2024-10-13 13:41:14

当你写

l = alist[:]

时,你正在做一个浅拷贝。也就是说,列表不同,但两个列表指向相同的对象。因此,如果您修改列表中的一个元素,则另一个列表中的元素也会被修改。

你需要制作一个深层副本,即。复制列表以及列表中的所有对象。

import copy
copy.deepcopy()

when you write

l = alist[:]

you're doing a shallow copy. that is to say that the list is different, but the two lists are pointing to the same objects. so if you modify one element of a list, the element in the other list will be modified too.

you need to make a deep copy, ie. copying the list and all the object in the list.

import copy
copy.deepcopy()
谁对谁错谁最难过 2024-10-13 13:41:14
>>> import copy
>>> help(copy)

在第一行中,您可以看到函数 copydeepcopy。它们对应于浅复制和深复制。详情请参考http://en.wikipedia.org/wiki/Object_copy

>>> import copy
>>> help(copy)

In the very first lines, you can see functions copy and deepcopy. These correspond to shallow and deep copying. For details, refer to http://en.wikipedia.org/wiki/Object_copy

未央 2024-10-13 13:41:14

我不会尝试修复深层副本,而是只需使用嵌套列表理解创建所需的数据。这也避免了最终数据的丑陋的手动“积累”。

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 

Instead of trying to fix up the deep copies, I would just create the desired data with nested list comprehensions. This also avoids the ugly manual "accumulation" of the final data.

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 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文