【问题标题】:Reassign variable to original value (defined prior to the loop) at start of each iteration in loop在循环中每次迭代开始时将变量重新分配给原始值(在循环之前定义)
【发布时间】:2014-07-30 11:27:57
【问题描述】:

在 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 列表每次迭代都会被覆盖。

我做错了什么?

【问题讨论】:

    标签: python loops variables iteration variable-assignment


    【解决方案1】:

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

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

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

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

    from copy import deepcopy
    
    new = deepcopy(original2D)
    

    或显式创建子列表的浅表副本,例如使用list comprehension:

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

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

    【讨论】:

      【解决方案2】:

      在 python 中,列表总是通过对象引用传递。因此,如果您像以前那样复制列表列表,您的列表中仍然会有相同的列表引用。你必须做一个深拷贝来解决你的问题。导入以下包,将new = original_2D[:]行改为:

      from copy import deepcopy
      
      original_2D = [['o', 'o', 'o'],['o', 'o', 'o']]
      for i in range(0,3):
          new = deepcopy(original_2D) # Change this line.
          new[0][i] = 'X'
          print new
      

      【讨论】:

      【解决方案3】:
      import copy
      original_2D = [['o', 'o', 'o'],['o', 'o', 'o']]
      for i in range(0,3):
          new = copy.deepcopy(original_2D[:])
          new[0][i] = 'X'
          print new
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-30
        • 2019-06-18
        • 2012-12-02
        • 1970-01-01
        • 2011-06-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多