SO上的常見問題是removing duplicates from a list of lists。由於名單是不可能的,set([[1, 2], [3, 4], [1, 2]])
投擲TypeError: unhashable type: 'list'
。這類問題的答案通常涉及使用元組,這些元組是不可變的,因此可排除。爲什麼讓列表不可用?
這個答案包括以下內容:
如果它被保存在字典中的特定插槽後的散列值的變化,這將導致不一致的字典。例如,最初該列表將被存儲在位置A處,該位置是基於散列值確定的。如果散列值發生變化,並且如果我們查找列表,我們可能無法在位置A找到它,或者根據新的散列值,我們可能會發現其他一些對象。
,但我不太理解,因爲其他類型的可用於字典鍵就可以沒有問題地改變:
>>> d = {}
>>> a = 1234
>>> d[a] = 'foo'
>>> a += 1
>>> d[a] = 'bar'
>>> d
{1234: 'foo', 1235: 'bar'}
很明顯,如果a
變化值時,它會出現亂碼到字典中的不同位置。 爲什麼對列表有相同的假設危險?爲什麼以下一種不安全的方法來散列列表,因爲當我們需要時,它就是我們所使用的方法?
>>> class my_list(list):
... def __hash__(self):
... return tuple(self).__hash__()
...
>>> a = my_list([1, 2])
>>> b = my_list([3, 4])
>>> c = my_list([1, 2])
>>> foo = [a, b, c]
>>> foo
[[1, 2], [3, 4], [1, 2]]
>>> set(foo)
set([[1, 2], [3, 4]])
看來,這解決了set()
問題,爲什麼這是一個問題?列表可能是可變的,但它們是有序的,看起來像是哈希需要的所有東西。
你並沒有修改存儲的**鍵**,而是將一個**新對象**分配給'a'。 –
這些都不一樣。在第一種情況下,您只需使用* * * *對象:1235而不是1234.它不是同一個對象發生了變異,列表中就是這種情況。 –
可能的重複[什麼使列表不可用?](http://stackoverflow.com/questions/23268899/what-makes-lists-unhashable) –