删除python列表中对象的实例
我认为这应该行得通,但它给了我一个错误。 我有一个包含类删除python列表中对象的实例,python,list,compare,Python,List,Compare,我认为这应该行得通,但它给了我一个错误。 我有一个包含类node的对象的列表。我有两个不同的清单 打开列表 节点列表。(它们在纵向、顺序上不相同) 当我在打开列表中找到特定节点时,我需要将其从节点列表中删除。我知道列表中有存储对象的地址 所以当我试着去做 removed = open_list.pop(min_index) node_list.remove(removed) 这给了我一个错误的说法 node_list.remove(removed) ValueError: list.rem
node
的对象的列表。我有两个不同的清单
打开列表
中找到特定节点时,我需要将其从节点列表
中删除。我知道列表中有存储对象的地址
所以当我试着去做
removed = open_list.pop(min_index)
node_list.remove(removed)
这给了我一个错误的说法
node_list.remove(removed)
ValueError: list.remove(x): x not in list
但是这个列表只包含了像指针一样的地址,对吗?它应该匹配相同的地址。我打印出了删除的的地址和整个节点列表
(现在只有10项不用担心)
打印输出:(节点_列表中的最后一项与删除的地址匹配:
removed: <__main__.node instance at 0x0124A440>
node_list: [<__main__.node instance at 0x01246E90>, <__main__.node instance at 0x01246EE0>, <__main__.node instance at 0x0124A300>, <__main__.node instance at 0x0124A328>, <__main__.node instance at 0x0124A350>, <__main__.node instance at 0x0124A378>, <__main__.node instance at 0x0124A3A0>, <__main__.node instance at 0x0124A3C8>, <__main__.node instance at 0x0124A3F0>, <__main__.node instance at 0x0124A418>, <__main__.node instance at 0x0124A440>]
已删除:
节点列表:[,,,,,,]
谢谢
随访Q
所以我想检查我要删除的节点是否存在于节点列表中
list.index(x)
和remove.index(x)
如果元素不在列表中,都会给出一个错误。这导致我的程序停止运行。
要绕过此问题,我可以在节点列表中的.remove()
:节点之前使用此语句
中的检查元素是否是列表的一部分并返回bool。
只是仔细检查一下
谢谢,之所以会发生这种情况,是因为您理解为标识节点
类的两个实例的特性,而不是python对它的理解
问题就在这里。假设您询问python5==5
,python将返回True
。这是因为python知道int
s。但是,Node
是您定义的自定义类,所以当两个Node
对象相同时,您需要告诉python。因为您(可能)还没有,python默认比较它们在内存中的位置。由于两个单独的实例将位于两个不同的内存位置,python将返回False
。如果您对Java非常熟悉,这就像==
和之间的区别一样。equals(…)
为此,进入节点
类并定义\uuuu eq\uuuu(self,other)
方法,其中other
应该是节点
的另一个实例
例如,如果节点有一个名为name
的属性,并且具有相同名称的两个节点被认为是相同的,则\uuuuuuuuuuuuuuuuuuuuuuuuuuuu
可以如下所示:
def __eq__(self, other):
myName = self.name
hisName = other.name
if myName == hisName:
return True
else:
return False
当然,编写相同函数更优雅的方式是:
def __eq__(self, other):
return self.name == other.name
完成此操作后,您的错误将消失
编辑1:响应的评论
class Node: pass
a = [Node(), Node()]
b = a[:]
b.remove(a.pop(0))
这是可行的。但仔细检查后,很明显a[0]和b[0]实际上是同一个对象。这可以通过调用id(a[0])
并将其与id(b[[0])
进行比较来验证,以确认它们确实是相同的
编辑2:回答OP的后续问题(作为编辑添加到原始问题)
是的,列表中不存在的对象将导致错误,该错误通常会停止程序流。这可以通过以下两种方法之一解决:
if x in my_list:
my_list.remove(x)
或
第二种方法尝试从my_list
中删除x
,如果这导致了一个错误,则忽略该错误如果我读对了问题,python默认比较内存位置的行为是他正在寻找的,但没有得到。下面是一个工作示例,其中定义了一个自定义类Node
,它表明没有必要使用\uuuuueq\uuuu(self,other)
我不能确定,因为您没有显示定义了打开节点列表
和节点列表
的位置,但我怀疑列表本身引用了相同的列表对象。如果是这种情况,则从打开节点列表
弹出的窗口也从节点列表
弹出,因此当您u调用remove
。下面是一个示例,其中node\u list
和open\u node\u list
实际上是同一个列表,因此对其中一个的更改会影响另一个:
class Node(object):
pass
open_node_list = []
node_list = open_node_list # <-- This is a reference, not a copy.
open_node_list.append(Node())
print(node_list)
作为对您后续行动的回应,中的“是”
将检查列表中的成员资格,因此:
if removed in node_list: node_list.remove(removed)
不会给您错误。或者,您可以捕获错误:
try:
node_list.remove(removed)
except ValueError:
pass
所以只有一行代码,比如\uuuueq\uuuuuuo(self,node)
.hmm.。很高兴了解python。谢谢!不……不只是一行。我发布的只是函数的签名。你需要完全定义它(见我编辑的帖子)ohhh..好的,是的,我在python库中读到了这个函数,然后你的例子就有帮助了。谢谢!如果这是原因,我会有点惊讶。即使没有定义\uuuuuueq\uuuuuu
,类节点:pass;a=[Node(),Node();b=a[:];b.remove(a.pop(0))
应该可以,我想。顺便说一句,如果你可以查看的话,我有一个快速的跟进问题..谢谢。我不认为我引用了它们。它们是单独的全局列表。我通常只是在满足某些条件后将节点列表中的一些节点附加到打开列表中。它们确实包含对相同对象的引用tho.open\u list=[]closed\u list=[]node_list=[]通过一个循环初始化一个节点列表。然后,如果需要,执行其他操作并附加到open_列表中。顺便说一句,如果您可以查看它,我有一个快速的后续q。谢谢。
node_list = open_node_list[:]
if removed in node_list: node_list.remove(removed)
try:
node_list.remove(removed)
except ValueError:
pass