我正在写一个包含10个存储桶列表的简单哈希表。使用内置的hash()
计算索引,然后对表大小进行模化。但是,当我尝试在bucket对象的每一个bucket中追加它时,我会尝试在bucket对象上追加它。
我试着用不同的方法来定义,但结果总是一样的。我做错什么了?在
size = 10
HT = [ [] ] * size
def add_HT(data):
index = hash(data) % size
HT[index].append(data)
print HT
[[], [], [], [], [], [], [], [], [], []]
add_HT('hello')
[['hello'], ['hello'], ['hello'], ['hello'], ['hello'], ['hello'], ['hello'], ['hello'], ['hello'], ['hello']]
{cd1>定义一个引用列表。相反,定义如下:
正如Volatility和kindall已经解释过的,
HT = [ [] ] * size
复制了10个相同的空list
,而不是10个不同的空list
s。list
身份总是让新手程序员头疼,有时甚至连专家也会被咬。在他们已经向您展示了如何解决这个问题并得到10个不同的空
list
s,但是还有另一种方法可以解决这个问题。如果您可以重写程序以完全不改变list
,那么它们是否相同并不重要:现在:
^{pr2}$这里的情况是,每次追加时都会生成一个新的bucket,并替换旧的bucket,所以bucket是不可变的。(您可能希望将它们存储为
tuple
s,而不是list
s,以确保不会意外地使它们突变。)您可以更进一步,不仅使每个
HT[i]
不可变,而且使HT
本身保持不变:有时使事物不可变会使代码更简单,有时更复杂。(在本例中,我认为第一个不可变版本和可变版本一样简单,但是第二个版本的可读性较差。)有时它使代码更快,有时更慢。(在本例中,快速测试显示第一个速度大致相同,但第二个速度慢了50倍,并且使用了更多的内存。另一方面,使用PyPy而不是CPython,它们的速度分别慢了15%和30%。)但这总是让你更容易思考,不必担心对象身份。除非它使事情更容易写,更容易阅读,而且更快,有一个折衷,你必须考虑。但知道怎么做是值得的。在
HT = [ [] ] * size
使size
指向同一列表的指针数目。add_HT
不是这里的问题。您需要将HT
定义为[[] for i in xrange(size)]
。在相关问题 更多 >
编程相关推荐