Python TypeError:不可损坏的类型

Python TypeError:不可损坏的类型,python,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)) 但这给了我一个错误 TypeError: unhashable type: 'list' 我有两个问题要问Python大师: a) 当我看一下Hashable的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))
但这给了我一个错误

TypeError: unhashable type: 'list'
我有两个问题要问Python大师:

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

“如果对象的哈希值在其生存期内从未更改,则该对象是可哈希的(它需要一个哈希()方法)”

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

dir([(a,b)for a in range(3)]for b in range(3))
它似乎在说
\uuuuuuuuuuuuuuuuuuuuuuuuu
就在那里。那么,为什么我会得到这个错误呢

我能够得到
[(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))

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

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


列表不使用散列进行索引,因此它不局限于可散列的项目。

您会发现
列表的实例不提供
\uuuuuuhash\uuuuu
——相反,每个列表的属性实际上是
None
(请尝试
打印[].\uuuuuuuhash\uu
)。因此,
list
是不可损坏的


代码使用
list
而不是
set
的原因是
set
构造了一组没有重复项的项目,而列表可以包含任意数据。

您正在通过
set(…)
调用创建一个
set
,而
set
需要散列项目。不能有一组列表。因为列表是不可散列的

[[(a,b)表示范围(3)中的a)]表示范围(3)中的b)]
是一个列表。它不是可散列类型。您在dir(…)中看到的
\uuuuuuuuuuu散列\uuuuuuu
不是一个方法,它只是一个都没有

列表理解返回一个列表,您不需要在那里显式使用列表,只需使用:

>>> [[(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)]]
试试这些:

>>> 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'
>a={1,2,3}
>>>b=[1,2,3]
>>>类型(a)
>>>类型(b)
>>> {1, 2, []}
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:不可损坏的类型:“列表”
>>>打印([]。\uuuu散列\uuuu)
没有一个
>>>[]、[]、[]#列表列表
[[], [], []]
>>>{[],[],[]}#列表集
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:不可损坏的类型:“列表”

。。。所以你应该这样做:

set(tuple ((a,b) for a in range(3)) for b in range(3))

。。。如果需要,将其转换回列表

real的原因是因为
set
不起作用,它使用哈希函数来区分不同的值。这意味着集合只允许散列对象。列表不可散列的原因已经指出。

TLDR: -你不能将一个列表、一个集合或一个dict散列成集合 -可以对元组进行散列,将其放入一个集合中。 例如:

>>> {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)])
>{1,2,3,4]}
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:不可损坏的类型:“列表”
>>> {1, 2, (3, 4)}
集合([1,2,(3,4)])
请注意,哈希在某种程度上是递归的,对于嵌套项,上述情况适用:

>>> {1, 2, 3, (4, [2, 3])}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>{1,2,3,(4,2,3])
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:不可损坏的类型:“列表”

Dict键也是可散列的,因此上面的Dict键也适用

我正在处理列表列表,所以这实际上非常有用。谢谢。通过例如
repr([1,2,3])
创建列表的元组表示比字符串表示更快,对吗?嵌套列表呢?@Alexandril对于嵌套列表,您可以使用理解,例如,对于二维列表
a=[[1,2],[3,4].#一个2乘2的矩阵可以通过
a=set(tuple(tuple(x)表示a中的x))
进行转换,那么什么类型是不可损坏的呢?