所以我最近一直在学习列表的可变属性,以及变量如何在Python中运行,以及从我的理解下面的代码应该有效:
def history(function, toAdd):
global history1
global history2
global history3
global history4
global history5
if function == 'add':
history5 = history4[:]
history4 = history3[:]
history3 = history2[:]
history2 = history1[:]
history1 = toAdd[:]
elif function == 'undo':
toReturn = history1[:]
history1 = history2[:]
history2 = history3[:]
history3 = history4[:]
history4 = history5[:]
return(toReturn[:])
elif function == 'return':
return(history1[:])
但由于某种原因,我传递给历史的列表,
history('add', lst[:])
仍然链接变量,这意味着当我在lst中更改某些内容时,我也会更改history1。我也尝试使用list()而不是[:]但是产生相同的结果。我在这里缺少什么?
答案 0 :(得分:1)
您缺少的是lst[:]
只是一个浅层副本。那个新的清单
返回可以添加和删除元素而不影响原始元素
列表,但列表中包含的引用仍然是共享的。所以修改
一个元素,比如说original_list[1].fooBar()
,会影响这两个参考
包含在原始列表和新列表中,因为它们是相同的
参考
您需要查看使用deepcopy()
(请参阅copy modules's Python
docs) - 但是,随附
它是一组自己的问题(不支持它的对象,复制太多等等)。
在你的情况下,它可能意味着history('add', lst[:])
应该是真的
类似于:history('add', copy.deepcopy(lst))
。
您的示例看起来还有其他一些问题。你可能 不想一直创建副本,而是一旦它进入就创建副本 这段历史,可能再次离开?我不确定我理解 真正的问题,所以这可能是糟糕的建议,但我希望代码更多 像:
def history(function, toAdd):
global history1
global history2
global history3
global history4
global history5
if function == 'add':
history5 = history4
history4 = history3
history3 = history2
history2 = history1
history1 = copy.deepcopy(toAdd)
elif function == 'undo':
toReturn = history1
history1 = history2
history2 = history3
history3 = history4
history4 = history5
# Should history5 still be valid at this point? Maybe do?
# history5 = None
# There could be several issues here. Remember, this is a deep copy
# of a previous object/collection. If your code is expecting the
# original object, you will not have it.
return toReturn
elif function == 'return':
# Is it expected that whomever calls this will receive a copy that
# they can manipulate? If so, the deepcopy() here is required.
return copy.deepcopy(history1)
我在上面留下了一些笔记,我认为你应该关注它 的东西。我还会考虑更多地简化这段代码:
from collections import deque
_history_store = deque(maxlen=5)
def history(function, toAdd):
global _history_store
if function == 'add':
_history_store.append(copy.deepcopy(toAdd))
elif function == 'undo':
if _history_store:
return _history_store.pop()
# No history to return.
return None
elif function == 'return':
if _history_store:
return copy.deepcopy(_history_store[-1])
# No history to return.
return None
使用双端队列将有助于将大小限制为5个条目,而无需这样做 所有人都在洗牌。