删除python列表中的对象实例
问题描述
我认为这应该可行,但它给了我一个错误.我有一个包含类 node
对象的列表.我有两个不同的列表
I Think this should work but its giving me an error.
I have a list that contains objects of class node
. I have two different lists
- 打开列表
- node_list.(它们的长度不同,顺序不同)
当我在 open_list
中找到特定节点时,我需要将其从 node_list
中删除.我知道这些列表具有存储在其中的对象的地址
When I find a specific node in the open_list
I need to delete it from the node_list
. I know that the lists have addresses to the objects stored in them
所以当我尝试这样做时
removed = open_list.pop(min_index)
node_list.remove(removed)
它给了我一个错误提示
node_list.remove(removed)
ValueError: list.remove(x): x not in list
但是列表只包含像指针一样的地址,对吧?它应该匹配相同的地址.我打印了 removed
的地址和整个 node_list
(现在只有 10 个项目,不要害怕)打印出:(node_list中最后一项匹配removed的地址:
but the list just contains addresses that act like pointers right? it should match up the same addresses. i printed out the address of removed
and the whole node_list
(only 10 items for now don't fear)
print out: (the last item in node_list matches the address of removed:
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
所以我想检查我要删除的节点是否存在于 node_list 中.当我在 http://docs.python.org/tutorial/datastructures.html 上查找一些简单的列表函数时
so I want to check if the node i want to remove exists in the node_list. when i looked up some simple list functions on http://docs.python.org/tutorial/datastructures.html
list.index(x)
和 remove.index(x)
都会给出错误.这导致我的程序停止运行.为了绕过这个,我可以在 .remove()
之前使用这个语句吗: node in node_list
我认为 in
检查是否有一个元素是列表的一部分并返回一个布尔值.只是双重检查谢谢,
list.index(x)
and remove.index(x)
both give an error if the element is not in the list. this caused my program to stop running.
to bypass this, can i use this statement before the .remove()
: node in node_list
i think the in
checks to see if an element is part of a list and returns a bool.
just double checking
thanks,
解决方案
发生这种情况是因为你理解为识别 Node
类的两个实例的特征,而不是 python 理解它的方式.
This is happening because what you understand as identifying features of two instances of your Node
class, is not how python understands it.
问题就在这里.假设你问 python 5==5
,python 会返回 True
.这是因为 python 知道 int
s.但是,Node
是你定义的自定义类,所以当两个 Node
对象相同时,你需要告诉 python.由于您(可能)没有,python 默认比较它们在内存中的位置.由于两个单独的实例将位于两个不同的内存位置,python 将返回 False
.如果你完全熟悉 Java,这就像 ==
和 .equals(...)
The problem lies here. Suppose you asked python 5==5
, python would return True
. This is because python knows about int
s. However, Node
is a custom class that you defined, so you need to tell python when two Node
objects are the same. Since you (probably) haven't, python defaults to comparing their locations in memory. Since two separate instances will be in two different memory locations, python will return False
. If you are familiar with Java at all, this is like the difference between ==
and .equals(...)
为此,请进入您的 Node
类并定义 __eq__(self, other)
方法,其中 other
是预期的成为 Node
的另一个实例.
In order to do this, go into your Node
class and define the __eq__(self, other)
method, where other
is expected to be another instance of Node
.
例如,如果您的节点有一个名为 name
的属性,并且两个具有相同名称的节点被认为是相同的,那么您的 __eq__
可能如下所示:
For example, if your nodes have an attribute called name
and two nodes that have the same name are considered to be the same, then your __eq__
could look like this:
def __eq__(self, other):
myName = self.name
hisName = other.name
if myName == hisName:
return True
else:
return False
当然,编写相同函数的更优雅的方式是:
Of course, the more elegant way of writing that same function is:
def __eq__(self, other):
return self.name == other.name
完成后,您的错误应该消失
When this is done, your error should disappear
编辑 1:回应 DSM 的评论
class Node: pass
a = [Node(), Node()]
b = a[:]
b.remove(a.pop(0))
这会奏效.但仔细观察后,很明显 a[0] 和 b[0] 实际上是同一个对象.这可以通过调用 id(a[0])
并与 id(b[[0])
进行比较来确认它们确实相同
This will work. But upon closer inspection, it becomes evident that a[0] and b[0] are in fact the same object. This can be verified by calling id(a[0])
and comparing it with id(b[[0])
to confirm that they are indeed the same
编辑 2:针对 OP 的后续问题(作为编辑添加到原始问题)
EDIT 2: In response to the OP's follow up question (added to the original question as edit)
是的,列表中不存在的对象将导致通常会停止程序流的错误.这可以通过以下两种方式之一解决:
Yes, the object not existing in the list will cause an error which would normally stop program flow. This can be solved in either of the following two ways:
if x in my_list:
my_list.remove(x)
或
try:
my_list.remove(x)
except:
pass
第二种方法尝试从 my_list
中删除 x
,如果导致错误,则忽略错误
The second method attempts to remove x
from my_list
and if that results in an error, ignores the error
相关文章