set()脱重原理
文書ディレクトリスタート カスタムデータ構造 __eq__関数 __hash__関数 重量除去原理 スタート
周知のようにset()はPythonの「天然脱重因子」である.一連のデータ、例えばlyst=[1,1,2,4,4]に対して、私たちはよくsetして、つまり:
では、set()はどのようにして重くしますか?
カスタムデータ構造
実際の開発ニーズに合わせるためには、データ構造をカスタマイズする必要があります.一般的な例Studentで言えば.
次に、stu 1とstu 2の2つのStudioオブジェクトを例に挙げます.名前はname、年齢age、学号sidと同じです.現実の生活では、この二人の学生は同じ人だと考えられる.
しかしset()はそうは思わないので,デウェイト効果は実現しなかった.
__eq__関数#カンスウ#
実際、比較オペレータ
プログラムが現実的なニーズに従って実行されていないため、このような現象が発生します.現実的なニーズは、名前、年齢、学号が同じであれば、きっと同じ人なので、魔法の方法
今、setで重くすることができますか?
残念ながら、解釈器が間違っています.Studioタイプのオブジェクトはハッシュできないということです.
__hash__関数#カンスウ#
Studioに
便宜上、ここではtupleの可変特性を用いて、ハッシュ処理を正しく通過させることができる.この時私たちはset()で重くして、成功したことを発見しました!
上記のコードに基づいてeq関数を削除しようとすると、set()が再失効していることがわかります.ハッシュの結果は同じですが.
げんじゅうげんり
前のステップで導いたように、set()の重み付け原理も得られました. set()関数では、オブジェクトの hash結果が同じであれば、比較オペレータ もしすべて等しいならば、重さを取り除きます;そうでなければset()は両者が異なり,両方とも結果に残ると考えられる.
周知のようにset()はPythonの「天然脱重因子」である.一連のデータ、例えばlyst=[1,1,2,4,4]に対して、私たちはよくsetして、つまり:
set(lyst)
、重み付けの目的を達成します.では、set()はどのようにして重くしますか?
カスタムデータ構造
実際の開発ニーズに合わせるためには、データ構造をカスタマイズする必要があります.一般的な例Studentで言えば.
class Student(object):
def __init__(self, name, age, sid):
self.name = name
self.age = age
self.sid = sid
次に、stu 1とstu 2の2つのStudioオブジェクトを例に挙げます.名前はname、年齢age、学号sidと同じです.現実の生活では、この二人の学生は同じ人だと考えられる.
stu1 = Student("zhong", 15, 11198)
stu2 = Student("zhong", 15, 11198)
print(set([stu1, stu2]))
# :{<__main__.student object="" at="">, <__main__.student object="" at="">}
しかしset()はそうは思わないので,デウェイト効果は実現しなかった.
__eq__関数#カンスウ#
実際、比較オペレータ
==
を使用すると、Python解釈器はstu 1がstu 2に等しくないと考えていることがわかります.print(stu1 == stu2) # :False
プログラムが現実的なニーズに従って実行されていないため、このような現象が発生します.現実的なニーズは、名前、年齢、学号が同じであれば、きっと同じ人なので、魔法の方法
__eq__()
を書き直す必要があります.コードは次のとおりです.class Student(object):
def __init__(self, name, age, sid):
self.name = name
self.age = age
self.sid = sid
def __eq__(self, other):
return self.name == other.name and \
self.age == other.age and \
self.sid == other.sid
stu1 = Student("zhong", 15, 11198)
stu2 = Student("zhong", 15, 11198)
print(stu1 == stu2) # :True
今、setで重くすることができますか?
print(set([stu1, stu2]))
---------------------------------
Traceback (most recent call last):
File "xxxxxxxxx", line 18, in <module>
print(set([stu1, stu2]))
TypeError: unhashable type: 'Student'
残念ながら、解釈器が間違っています.Studioタイプのオブジェクトはハッシュできないということです.
__hash__関数#カンスウ#
Studioに
__eq__()
関数を追加していない場合、set()はまだエラーを報告していませんが、今はハッシュできませんか?幸いなことに、__hash__()
メソッドを書き換えて、元のデフォルトのハッシュ処理ロジックを変更することができます.class Student(object):
def __init__(self, name, age, sid):
self.name = name
self.age = age
self.sid = sid
def __eq__(self, other):
return self.name == other.name and \
self.age == other.age and \
self.sid == other.sid
def __hash__(self):
return hash((self.name, self.age, self.sid))
stu1 = Student("zhong", 15, 11198)
stu2 = Student("zhong", 15, 11198)
print(set([stu1, stu2]))
# :{<__main__.student object="" at="">}
便宜上、ここではtupleの可変特性を用いて、ハッシュ処理を正しく通過させることができる.この時私たちはset()で重くして、成功したことを発見しました!
上記のコードに基づいてeq関数を削除しようとすると、set()が再失効していることがわかります.ハッシュの結果は同じですが.
class Student(object):
def __init__(self, name, age, sid):
self.name = name
self.age = age
self.sid = sid
def __hash__(self):
return hash((self.name, self.age, self.sid))
stu1 = Student("zhong", 15, 11198)
stu2 = Student("zhong", 15, 11198)
print(set([stu1, stu2])) # :{<__main__.student object="" at="">, <__main__.student object="" at="">}
print(hash(stu1) == hash(stu2)) # : True
げんじゅうげんり
前のステップで導いたように、set()の重み付け原理も得られました.
__hash__()
メソッドが先に呼び出され、hash結果が取得されます.==
(すなわち呼び出し関数__eq__()
)で両者の値が等しいか否かを判断する.