Python:过滤Hero对象列表时获取对象引用而非副本的方法
关于Python列表推导式过滤对象列表是否保留引用的解答
放心啦,你的担心完全是多余的!在Python里,列表推导式[x for x in Heroes if x.alive]并不会复制Hero对象本身,新列表filtered_list里存储的都是原列表中符合条件的Hero对象的引用,和原列表里的对象是同一个实例。
为什么会这样?
Python的变量和列表元素本质上都是对象的引用,而非对象本身。当你遍历Heroes列表时,x指向的就是原列表中的某个Hero对象,把x加入新列表,只是把这个对象的引用复制到了新列表里,并没有创建对象的副本。也就是说,filtered_list里的元素和Heroes中对应的对象是同一个,修改其中一个的属性,另一个也会同步变化。
实际例子验证
我们用你的Hero类简化写个例子:
class Hero: def __init__(self, name, player_index): self._alive = True self.name = name self.player_index = player_index @property def alive(self): return self._alive @alive.setter def alive(self, value): self._alive = value # 创建Hero对象列表 Heroes = [ Hero("战士", 0), Hero("法师", 1), Hero("刺客", 2), Hero("辅助", 3) ] # 把法师设为死亡状态 Heroes[1].alive = False # 用列表推导式过滤存活英雄 filtered_list = [x for x in Heroes if x.alive] # 修改filtered_list里战士的名字 filtered_list[0].name = "重装战士" # 查看原列表中战士的名字,会发现已经被修改了 print(Heroes[0].name) # 输出: 重装战士
从这个例子能明显看到,修改filtered_list里的对象属性,原列表对应的对象也跟着变了,这就证明了新列表里存的是原对象的引用,不是副本。
所以你完全可以放心使用这个列表推导式来过滤,它完全满足你“获取对象引用而非副本”的需求~
内容的提问来源于stack exchange,提问作者Darren Christopher
相关产品推荐
相关产品推荐

