如果您在python中有一个列表(原始),如:
class CustomID (object):
def __init__(self, *args):
self.ID = ''
self.manymore = float()
self.visited = False
self.isnoise = False
IDlist = ['1','2','3','4','5','6','7','8','9','10']
Original = list()
for IDs in IDlist:
NewObject = CustomID()
NewObject.ID = IDs
Original.append(NewObject)
如果您对新列表和要在理解子列表中使用的函数有所了解:
def Func(InputList=list()):
for objects in InputList:
objects.visited = True
return InputList
New_List = [member for member in Original if (int(member.ID)>5)]
ThirdList = Func(New_List)
此(New_List)是否会导致原始列表的浅或深副本?这个问题对我来说很重要,如果原始列表包含对象,哪些属性可以在代码中更改以遵循New_List创建(ThirdList)。 New_list被发送到一个函数,它将改变属性。问题是,如果您尝试将原始列表重用于具有不同理解的相同功能(假设(成员> 4)。
New_List = [member for member in Original if (int(member.ID)>4)]
实际上:
print New_List[3].visited
给出了真实。
答案 0 :(得分:4)
您正在创建一个浅的过滤副本。
你的循环不会创建member
的副本,它会直接引用它们。
不是您需要创建副本,原始列表中的所有对象都是不可变整数。此外,CPython实习小整数,创建副本只会导致完全相同的对象用于这些。
为了说明,请尝试创建包含可变对象的列表的副本。我在这里使用了一本字典:
>>> sample = [{'foo': 'bar'}]
>>> copy = [s for s in sample]
>>> copy[0]['spam'] = 'eggs'
>>> copy.append({'another': 'dictionary'})
>>> sample
[{'foo': 'bar', 'spam': 'eggs'}]
copy
列表是一个新的列表对象,包含对sample
中包含的同一字典的引用。更改该字典会反映在copy
和sample
中,但附加到copy
不会改变原始列表。
对于更新后的循环代码,您的示例会生成一个仍然共享对象的New_List
列表,而New_List[3].visited
实际上是True
:
>>> New_List[3].ID
'8'
>>> New_List[3].visited
True
因为它仍然是Original
索引7处的相同对象:
>>> New_List[3] is Original[7]
True
与ThirdList
索引2中仍然存在的对象相同:
>>> ThirdList[2] is New_List[3]
True
答案 1 :(得分:0)
另一个对我有用的想法是在类
中实现flagClear方法class CustomID (object):
def __init__(self, *args):
self.ID = ''
self.manymore = float()
self.visited = False
self.isnoise = False
def flagClear(self):
self.visited = False
return self
然后,每次我构建一个新列表时,只需使用该方法:
New_List = [member.flagClear() for member in Original if (int(member.ID)>4)]
如果我在CustomID中修改的唯一内容是.visited标志,那么这可行。显然,它不会是完美的。如果有人需要一个完整的解决方案,Martijn Pieters的建议将最有效(实现.copy()方法):
import copy
class CustomID (object):
def __init__(self, *args):
self.ID = ''
self.manymore = float()
self.visited = False
self.isnoise = False
def CustomCopy(self):
return copy.deepcopy(self)
New_List = [member.CustomCopy() for member in Original if (int(member.ID)>4)]
谢谢Martijn,这对我来说真是一次学习经历。