小能豆

在循环中每次迭代开始时将变量重新分配给原始值(在循环之前定义)

py

在 Python 中,在每次迭代开始时将变量重新分配给原始值(在循环之前定义)时使用[:]。也就是说:

original_1D = ['o', 'o', 'o']
for i in range(0,3):
  new = original_1D[:]       # revert back to 'original_1D' list defined before loop
  new[i] = 'X'
  print new

产生的输出符合预期:

['X', 'o', 'o']
['o', 'X', 'o']
['o', 'o', 'X']

如果原始列表是多维的(original_2D),则会出现我的问题。例如:

original_2D = [['o', 'o', 'o'],['o', 'o', 'o']]
for i in range(0,3):
  new = original_2D[:]       # revert back to 'original_2D' list defined before loop
  new[0][i] = 'X'
  print new

由此,我想要以下输出:

# Desired
[['X', 'o', 'o'], ['o', 'o', 'o']]
[['o', 'X', 'o'], ['o', 'o', 'o']]
[['o', 'o', 'X'], ['o', 'o', 'o']]

但不行!我得到了这个:

# Actual
[['X', 'o', 'o'], ['o', 'o', 'o']]
[['X', 'X', 'o'], ['o', 'o', 'o']]
[['X', 'X', 'X'], ['o', 'o', 'o']]

好像original_2D列表在每次迭代中都会被覆盖。


阅读 15

收藏
2024-12-12

共1个答案

小能豆

[:]在 Python 中,将变量重新赋值给原始值时使用

不,您使用它来创建序列的全长切片(即浅拷贝) 。如果原始值是不可变序列(例如字符串和元组),则没有必要,如果原始值不是序列,则它将不起作用。

请注意,我上面强调了浅拷贝- 切片创建的新对象包含对与原始对象相同的对象的引用。 如果原始序列包含对可变对象(例如列表)的引用,则可能会出现问题。

要么使用copy.deepcopy创建深(而不是浅)副本:

from copy import deepcopy

new = deepcopy(original2D)

或者明确创建子列表的浅表副本,例如使用列表理解

new = [row[:] for row in original2D]

前者更容易扩展到更高的维度。

2024-12-12