Reassign variable to original value (defined prior to the loop) at start of each iteration in loop

穿精又带淫゛_ 提交于 2019-12-25 02:26:56

问题


In Python, you use [:] when reassigning a variable to an original value (defined prior to the loop) at the start of each iteration. That is to say:

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

produces output that is both desired and expected:

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

My issue arises if the original list is multi-dimensional (original_2D). For example:

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

From this, I want the following output:

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

but no! I get this:

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

as if the original_2D list gets overwritten which each iteration.

What am I doing wrong?


回答1:


In Python, you use [:] when reassigning a variable to an original value

No, you use it to create a full-length slice (i.e. shallow copy) of a sequence. If the original value is an immutable sequence (e.g. strings and tuples) it's unnecessary, and if the original value isn't a sequence it won't work.

Note that I have emphasised shallow copy above - the new object created by the slice contains references to the same objects as the original. If your original sequence contains references to mutable objects (like, for example, lists), this can be a problem.

Either use copy.deepcopy to create a deep (rather than shallow) copy:

from copy import deepcopy

new = deepcopy(original2D)

or explicitly create shallow copies of the sub-lists too, using e.g. a list comprehension:

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

The former scales more easily to higher dimensions.




回答2:


In python lists are always passed by object reference. So if you copy a list of lists like you did, you will still have the same list references in your list. You have to make a deep copy to solve your problem. Import the following package and change the line new = original_2D[:] to:

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


来源:https://stackoverflow.com/questions/25035664/reassign-variable-to-original-value-defined-prior-to-the-loop-at-start-of-each

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!