以下代码定义了一个类 (Wall),当它被实例化时,对象被添加到一个列表 (in_progress) 中,一旦它的属性 (progress) 达到 3,它就会从该列表中删除并移动到另一个列表 (built)。
in_progress = []
built = []
class Wall:
global in_progress, built
def __init__(self):
self.progress = 0
in_progress.append(self)
def build(self):
self.progress += 1
if self.progress == 3:
in_progress.remove(self)
built.append(self)
这很方便,因为无论列表“in_progress”中有多少墙,我都可以运行:
for wall in in_progress:
wall.build()
最终“in_progress”将是空的。但是我做了一些测试,当 in_progress 中的一个实例达到 progress = 3 时,一些奇怪的事情发生了。
例如。让我们实例化三堵墙:
Wall()
Wall()
Wall()
#check in_progress
in_progress
--->
[<__main__.Wall at 0x7f4b84e68cf8>,
<__main__.Wall at 0x7f4b84e68c50>,
<__main__.Wall at 0x7f4b84e68f28>]
#check attribute progress
for wall in in_progress:
print(f'{wall}: {wall.progress}')
--->
<__main__.Wall object at 0x7f4b84e68cf8>: 0
<__main__.Wall object at 0x7f4b84e68c50>: 0
<__main__.Wall object at 0x7f4b84e68f28>: 0
#'build' on them 2 times
for wall in in_progress:
wall.build()
for wall in in_progress:
print(f'{wall}: {wall.progress}')
--->
<__main__.Wall object at 0x7f4b84e68cf8>: 2
<__main__.Wall object at 0x7f4b84e68c50>: 2
<__main__.Wall object at 0x7f4b84e68f28>: 2
如果我们再次运行最后一段代码,我们预计会发现列表 in_progress 是空的,但我们发现的是:
#'build' on them once more
for wall in in_progress:
wall.build()
for wall in in_progress:
print(f'{wall}: {wall.progress}')
--->
<__main__.Wall object at 0x7f4b84e68c50>: 2
如果我们检查 build 的列表,我们会发现剩下 2 面墙,但应该有 3 面。 为什么会这样?
最佳答案
您的构建函数中的问题是您试图修改您正在迭代的同一个列表,这导致了这个奇怪的问题发生,尝试如下,您应该看不到这个问题。我正在通过 copy.copy https://docs.python.org/3/library/copy.html 将列表复制到另一个变量
import copy
in_progress = []
built = []
class Wall:
global in_progress, built
def __init__(self):
self.progress = 0
in_progress.append(self)
def build(self):
global in_progress
self.progress += 1
#Make a copy of the list and operate on that
copy_in_progress = copy.copy(in_progress)
if self.progress == 3:
copy_in_progress.remove(self)
built.append(self)
in_progress = copy_in_progress
Wall()
Wall()
Wall()
print(in_progress)
#[<__main__.Wall object at 0x108259908>,
#<__main__.Wall object at 0x108259940>,
#<__main__.Wall object at 0x1082599e8>]
for wall in in_progress:
print(f'{wall}: {wall.progress}')
#<__main__.Wall object at 0x108259908>: 0
#<__main__.Wall object at 0x108259940>: 0
#<__main__.Wall object at 0x1082599e8>: 0
for wall in in_progress:
wall.build()
wall.build()
for wall in in_progress:
print(f'{wall}: {wall.progress}')
#<__main__.Wall object at 0x108259908>: 2
#<__main__.Wall object at 0x108259940>: 2
#<__main__.Wall object at 0x1082599e8>: 2
for wall in in_progress:
wall.build()
for wall in in_progress:
print(f'{wall}: {wall.progress}')
#Nothing is printed
关于python - 从内部添加和删除实例到列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55506417/