ボラティリティとキンダルがすでに説明したように、10個の異なる空ではなくHT = [ [] ] * size
、同じ空の10個のコピーを作成します。アイデンティティは常に初心者のプログラマーを噛み、時には専門家さえも噛みます。list
list
list
彼らはすでに問題を解決し、10個list
の異なる空を取得する方法を示しました。しかし、この問題を回避する別の方法があります。をまったく変更しないようにプログラムを書き直すことができる場合、list
それらが同じであるかどうかは関係ありません。
def add_HT(data):
index = hash(data) % size
HT[index] = HT[index] + [data]
今:
>>> add_HT('hello')
>>> add_HT('goodbye')
>>> HT
[['goodbye'], ['hello'], [], [], [], [], [], [], [], []]
ここで起こっていることは、追加するたびに新しいバケットを作成し、古いバケットを置き換えるため、バケットは不変です。(誤って変更しないように、tuple
sではなくsとして保存することをお勧めします。)list
これをさらに進めて、それぞれをHT[i]
不変にするだけでなく、HT
それ自体も不変にすることができます。
def add_HT(data):
global HT
index = hash(data) % size
HT = [bucket if i != index else bucket + [data] for i, bucket in enumerate(HT)]
物事を不変にすることで、コードが単純になることもあれば、より複雑になることもあります。(この場合、最初の不変バージョンは可変バージョンとほぼ同じくらい単純だと思いますが、2番目のバージョンははるかに読みにくくなります。)コードが速くなることもあれば、遅くなることもあります。(この場合、簡単なテストでは、最初の速度はほぼ同じですが、2番目の速度は50倍遅く、より多くのメモリを使用します。一方、CPythonの代わりにPyPyを使用すると、15%と30%になります。それぞれ遅くなります…)しかし、それは常に推論を容易にします—オブジェクトのアイデンティティについて心配する必要はありません。書きやすく、読みやすく、高速になる場合を除いて、考慮しなければならないトレードオフがあります。しかし、それを行う方法を知ることは価値があります。