これはうまくいくはずですが、エラーが発生します。クラスnode
のオブジェクトを含むリストがあります。私は2つの異なるリストを持っています
_open_list
_で特定のノードを見つけたら、それを_node_list
_から削除する必要があります。リストに格納されているオブジェクトのアドレスがあることを知っています
だから私がやろうとすると
_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: <__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>]
_
ありがとう
削除したいノードがnode_listに存在するかどうかを確認したいと思います。 http://docs.python.org/tutorial/datastructures.html でいくつかの簡単なリスト関数を調べたとき
要素がリストにない場合、list.index(x)
とremove.index(x)
の両方でエラーが発生します。これにより、プログラムの実行が停止しました。これを回避するには、.remove()
の前にこのステートメントを使用できますか:_node in node_list
_ in
は、要素がリストの一部であるかどうかを確認し、ブール値を返すと思います。感謝を再確認するだけです、
これは、Node
クラスの2つのインスタンスの機能を識別するものとして理解しているのは、pythonがそれを理解している方法ではないためです。
問題はここにあります。 python _5==5
_、pythonはTrue
を返します。これはpython = int
sについて知っています。ただし、Node
は定義したカスタムクラスであるため、2つのNode
オブジェクトがいつpythonあなたは(おそらく)そうではないので、pythonはデフォルトでメモリ内の場所を比較します。2つの別々のインスタンスが2つの異なるメモリ場所にあるため、pythonはFalse
を返します。Javaに精通している場合、これは_==
_と.equals(...)
の違いのようなものです。
これを行うには、Node
クラスに移動し、__eq__(self, other)
メソッドを定義します。ここで、other
はNode
の別のインスタンスであると想定されます。
たとえば、ノードにname
という属性があり、同じ名前の2つのノードが同じであると見なされる場合、___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
_
これが行われると、エラーは消えるはずです
EDIT 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])
と比較し、それらが実際に同じであることを確認することで確認できます。
編集2:OPのフォローアップ質問への応答(編集として元の質問に追加)
はい、リストに存在しないオブジェクトはエラーを引き起こし、通常はプログラムの流れを停止します。これは、次の2つの方法のいずれかで解決できます。
_if x in my_list:
my_list.remove(x)
_
OR
_try:
my_list.remove(x)
except:
pass
_
2番目の方法は、_my_list
_からx
を削除しようとし、その結果エラーが発生した場合、エラーを無視します
フォローアップに応じて、yes in
はリストのメンバーシップをチェックします。したがって、次のようになります。
if removed in node_list: node_list.remove(removed)
エラーは発生しません。または、エラーをトラップすることもできます。
try:
node_list.remove(removed)
except ValueError:
pass
私が質問を正しく読んだ場合、メモリ位置を比較するPythonのデフォルトは、彼が探している動作ですが、取得されていません。カスタムクラスがNode
で定義されている実際の例を次に示します。これは、__eq__(self, other)
が必要ないことを示しています。
class Node(object):
pass
open_node_list = []
node_list = []
for i in range(10):
a_node = Node()
open_node_list.append(a_node)
node_list.append(a_node)
removed = open_node_list.pop()
node_list.remove(removed)
open_node_list
とnode_list
がどこで定義されているかを示していないため、わかりませんが、リスト自体が同じリストオブジェクトを参照していると思われます。その場合、open_node_list
からのポップもnode_list
からポップするため、remove
を呼び出すとノードは存在しなくなります。 node_list
とopen_node_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)
リストをコピーする1つの方法は次のとおりです。
node_list = open_node_list[:]