TypeError:不可用的类型

pyl*_*ner 30 python

我试图得到一个元组列表的列表:类似于[ [(1,0),(2,0),(3,0)],[(1,1),(2,1),(3,1)....]] 我使用这个语句

set([(a,b)for a in range(3)]for b in range(3))
Run Code Online (Sandbox Code Playgroud)

但它给了我一个错误

TypeError: unhashable type: 'list'
Run Code Online (Sandbox Code Playgroud)

我对Python Guru有2个问题:

a)当我看到Hashable的Python定义时 -

"如果一个对象具有一个在其生命周期内永远不会改变的哈希值(它需要一个hash()方法),那么该对象是可以清除的"

当我在上面的表达式上使用dir函数时

dir([(a,b)for a in range(3)]for b in range(3))
Run Code Online (Sandbox Code Playgroud)

似乎说它就在__hash__那里.那么,为什么我会收到错误?

我能够[[(0, 0), (1, 0), (2, 0)], [(0, 1), (1, 1), (2, 1)], [(0, 2), (1, 2), (2, 2)]] 通过使用list命令获得:

list(list((a,b) for a in range(3)) for bin range(3))
Run Code Online (Sandbox Code Playgroud)

b)列表和设置都将Iterable作为参数.为什么一个工作(列表)而另一个不工作(设置)?

utd*_*mir 25

您正在创建一个set通过set(...)呼叫,并set需要可清洗的项目.你不能有一套清单.因为列表不可以清除.

[[(a,b) for a in range(3)] for b in range(3)]是一个清单.它不是一种可洗的类型.在__hash__你的dir(...)看到不是方法,它只是无.

列表推导返回一个列表,你不需要在那里明确使用列表,只需使用:

>>> [[(a,b) for a in range(3)] for b in range(3)]
[[(0, 0), (1, 0), (2, 0)], [(0, 1), (1, 1), (2, 1)], [(0, 2), (1, 2), (2, 2)]]
Run Code Online (Sandbox Code Playgroud)

试试那些:

>>> a = {1, 2, 3}
>>> b= [1, 2, 3]
>>> type(a)
<class 'set'>
>>> type(b)
<class 'list'>
>>> {1, 2, []}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> print([].__hash__)
None
>>> [[],[],[]] #list of lists
[[], [], []]
>>> {[], [], []} #set of lists
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
Run Code Online (Sandbox Code Playgroud)

  • 那么哪些类型是不可散列的呢? (2认同)

Gui*_*ier 11

对于那些来自谷歌搜索寻找一个简单答案的人:它可以与元组一起使用,但在创建集合时不适用于列表.

>>> {1, 2, [3, 4]}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

>>> {1, 2, (3, 4)}
set([1, 2, (3, 4)])
Run Code Online (Sandbox Code Playgroud)


Mar*_*som 6

列表是不可删除的,因为其内容可以在其生命周期内更改.您可以随时更新列表中包含的项目.

列表不使用散列进行索引,因此它不限于可散列项.


fra*_*sua 6

...所以你应该做这样的事情:

set(tuple ((a,b) for a in range(3)) for b in range(3))
Run Code Online (Sandbox Code Playgroud)

...如果需要转换回列表


sch*_*mar 6

因为不起作用的真正原因set是它使用散列函数来区分不同的值.这意味着集合仅允许可散列对象.为什么列表不可清除已经指出.