删除python列表中的对象的实例 [英] removing an instance of an object in python list
问题描述
我认为这应该工作,但它给我一个错误。
我有一个包含类 node
的对象的列表。我有两个不同的列表
- open_list
- node_list。明智的)
当我在 open_list
请从 node_list
中删除它。我知道列表中存储的对象的地址
所以当我尝试做
removed = open_list.pop(min_index)
node_list.remove(removed)
它给我一个错误,说
node_list.remove(已删除)
ValueError:list.remove (x):x不在列表中
但是列表只包含类似指针的地址?它应该匹配相同的地址。我打印出删除的地址
和整个 node_list
(现在只有10个项目不怕)
print out:(node_list中的最后一个项目匹配删除的地址:
已删除:< __ main __。node instance at 0x0124A300>>
node_list:[<__ main __。在0x01246E90处的节点实例,< __ main __。在0x01246EE0处的节点实例>,< __ main __。在0x0124A300处的节点实例> ;,< __ main __。 ; __主__。节点实例在0x0124A350>,< __ main __。节点实例在0x0124A378>,< __ main __。节点实例在0x0124A3A0>,< __ main __。节点实例在0x0124A3C8& ; __ main __。节点实例在0x0124A418>,< __ main __。node instance at 0x0124A440>]
/ p>
追踪Q
检查我想删除的节点是否存在于node_list中当我在 http:// docs上查找一些简单的列表函数时.python.org / tutorial / datastructures.html
list.index(x)
code> remove.index(x)如果元素不在列表中,都会产生错误。这使我的程序停止运行。
绕过这个,我可以在 .remove()
:节点之前使用这个语句node_list
i认为在
中检查一个元素是否是列表的一部分并返回一个bool。
只是双重检查
感谢,
这是因为你理解为识别两 Node
类的实例不是python理解的。
问题在这里。假设你问python 5 == 5
,python会返回 True
。这是因为python知道 int
。但是, Node
是你定义的一个自定义类,所以你需要告诉python当两个 Node
对象是相同的。因为你(可能)没有,python默认情况下比较他们在内存中的位置。因为两个单独的实例将在两个不同的内存位置,python将返回 False
。如果你熟悉Java,这就像 ==
和 .equals(...)之间的区别
为此,请进入节点
类并定义 __ eq__ (self,other)
方法,其中其他
预期是 Node
。
例如,如果你的节点有一个名为 name
的属性,并且两个节点名字相同那么您的 __ eq __
可能如下所示:
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
完成后,您的错误就会消失。
:为回应 DSM 的评论
class Node:pass
a = [Node(),Node()]
b = a [:]
b.remove(a.pop ))
这将工作。但是仔细检查后,很明显,a [0]和b [0]实际上是同一个对象。这可以通过调用
)id(a [0])
并与id(b [[0])
:为回应OP的后续问题(作为修改添加到原始问题中)。
是的,列表中不存在的对象将导致正常停止程序流的错误。这可以通过以下两种方式之一解决:
如果x在my_list中:
my_list.remove )
或
try:
my_list.remove(x)
except:
pass
第二种方法尝试从
my_list
中删除x
,如果导致错误,忽略错误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
- open_list
- node_list.( they are not the same lengthwise, ordering wise)
When I find a specific node in the
open_list
I need to delete it from thenode_list
. I know that the lists have addresses to the objects stored in themso when i try to do
removed = open_list.pop(min_index) node_list.remove(removed)
it gives me an error saying
node_list.remove(removed) ValueError: list.remove(x): x not in list
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 wholenode_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>]
Thanks
follow-up Q
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)
andremove.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 thein
checks to see if an element is part of a list and returns a bool. just double checking thanks,解决方案This is happening because what you understand as identifying features of two instances of your
Node
class, is not how python understands it.The problem lies here. Suppose you asked python
5==5
, python would returnTrue
. This is because python knows aboutint
s. However,Node
is a custom class that you defined, so you need to tell python when twoNode
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 returnFalse
. If you are familiar with Java at all, this is like the difference between==
and.equals(...)
In order to do this, go into your
Node
class and define the__eq__(self, other)
method, whereother
is expected to be another instance ofNode
.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
EDIT 1: In response to DSM's comment
class Node: pass a = [Node(), Node()] b = a[:] b.remove(a.pop(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 withid(b[[0])
to confirm that they are indeed the sameEDIT 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)
OR
try: my_list.remove(x) except: pass
The second method attempts to remove
x
frommy_list
and if that results in an error, ignores the error这篇关于删除python列表中的对象的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!