list.remove
という何となく奇妙な振る舞いに気付きましたが、少なくともCソースを使って説明することはできませんでした。list.removeの任意のクラス比較オブジェクトによる奇妙な振る舞い
は、このクラスを考えてみましょう:
class A:
def __init__(self, n1, n2):
self.n1 = n1
self.n2 = n2
def __eq__(self, other):
print('in eq')
return vars(self) == vars(other)
し、次のコード:
a1 = A(1, 2)
a2 = A(1, 2)
li = [a1, a2]
li.remove(a1)
私は出力in eq
にそれを期待するが、それはA.__eq__
を意味し、何も呼び出されていないされていない出力。
どちらもこの
a1 = A(1, 2)
a2 = A(2, 3)
li = [a1, a2]
li.remove(a1)
li.remove(a2)
はA.__eq__
への呼び出しをトリガしません。
最後までA.__eq__
を呼び出しますが、(奇妙なことが)一度だけん同じオブジェクトで二回remove
を呼び出す:
a1 = A(1, 2)
a2 = A(1, 2)
li = [a1, a2]
li.remove(a1)
li.remove(a1)
# 'in eq'
なぜ一度
remove
を呼び出すとA.__eq__
を呼び出すことはありませんか?remove
は、どのようにオブジェクトを削除することがわかっていますか?__eq__
をオーバーライドしても、比較のためにPythonの実装でメモリアドレスを使用するのは奇妙に思えます。- 同じオブジェクトで二回
remove
を呼び出すのはなぜは
A.__eq__
を呼び出すで、なぜ一度だけ?それは、すなわち__eq__
を==
を使用する前に
疑わられるように三度目
li.remove(a1)
を呼び出すとき。私たちが '__eq__'を上書きしたとしても、最初に' remove'を使うのは良い歴史的理由があるのだろうかと思います。私は得られたパフォーマンスが無視できると信じています。 – DeepSpace'' is'を比較する大きなリストがある場合、各リスト要素を個別に比較するよりもずっと速くなります。 –