所有的 Python 对象如字符串、整数、列表、字典和集合都有一个与之相关的可散列属性。有些对象是可散列的,而有些则不是。
当我们说一个Python对象是可散列的,这意味着该对象的值将保持不变,直到其寿命结束。例如,int、float 和字符串。
像列表、字典、集合和字节数组这样的 Python 对象是不可哈希的。意思是,这些对象的值可能会改变。例如,我们可以在这些对象中删除或添加一个元素。因此,值可能会改变。
了解TypeError的根本原因:unhashable类型:'numpy.ndarray'
在程序上,我们可以通过使用 [hash()](https://blog.finxter.com/python-hash-function/)函数。如果hash() ,返回一个数字,这表明该对象是可散列的。
比方说,我们有一个字符串。让我们看看当我们对字符串对象运行hash 函数时会发生什么。
s="Finxter"
print(hash(s))
输出
951412520483326359
当我们在一个字符串对象上运行hash() 函数时,会返回一个数字,表明它是一个可散列的对象。
现在,让我们看看当我们在一个ndarray 对象上运行哈希函数时会发生什么。
arr=np.array([1,2,3,4])
print(hash(arr))
输出
Traceback (most recent call last):
File "C:\Users\...\unhashable_type_ndarray.py", line 18, in <module>
print(hash(arr))
TypeError: unhashable type: 'numpy.ndarray'
我们看到一个错误,因为ndarray 对象不是可哈希的。
我知道你在想什么!
我的程序中没有hash() 函数。为什么我会看到这个错误?
这是因为你在程序中使用了字典或集合函数。而 dictionary keys和 设置元素必须是可哈希的。所以在内部,这些对象使用hash() 来验证你要添加的元素是否是可哈希的。关于更多细节,请查看集合和字典的源代码。
我们在以下情况下看到TypeError: unhashable type: 'numpy.ndarray' ,。
- 当我们把一个多维的
ndarray对象转换成一个集合对象时。 - 当我们把一个
ndarray对象指定为一个字典键时。 - 当我们把一个
ndarray对象添加到一个集合中时。
现在,让我们用一个例子来讨论这些情况中的每一种。
案例1:将一个多维的ndarray对象转换为一个set对象。
在 Python 中,一个可迭代对象可以使用 [set()](https://blog.finxter.com/python-set-function/)函数转换为集合对象。
注意,集合中的元素应该是强制性的可散列的。当我们在一个数组上调用set() 函数时,Python 解释器会检查该数组的元素是否是可散列的类型。如果是的话,ndarray 对象的元素就被转换为一个集合对象。
为了更好地理解这一点,让我们看一个例子。
import numpy as np
arr=np.array([1,2,3,4])
print(set(arr))
输出
{1, 2, 3, 4}
在上面的例子中,我们有一个数组[1,2,3,4] 。这个数组的元素是整数类型的。由于int 是一个可散列的类型,这个数组被成功地转换为一个集合对象。
现在,让我们看看当我们转换一个多维数组时会发生什么。
import numpy as np
arr=np.array([[1,2,3,4]])
print(set(arr))
输出
Traceback (most recent call last):
File "C:\Users\paian\PycharmProjects\Finxter\venv\share\unhashable_type_ndarray.py", line 4, in <module>
print(set(arr))
TypeError: unhashable type: 'numpy.ndarray'
在这种情况下,我们看到一个错误。因为 Python 解释器检查数组的元素是否是可散列的,它注意到该元素是一个ndarray 对象。一个错误显示出来,因为ndarray对象是不可哈希的。
修复。
为了解决这个错误,我们必须正确访问元素数据。在这种情况下,我们可以通过指定set(arr[0]) 来解决这个错误。
这在下面的代码片断中显示。
import numpy as np
arr=np.array([[1,2,3,4]])
print(set(arr[0]))
输出
{1, 2, 3, 4}
案例 2: 将一个 ndarray 对象指定为字典的关键字
在 Python 中,只有可散列的对象可以被添加为dictionarykey。如果你添加任何不可哈希的对象作为 dictionary key,你会看到一个错误。
请看下面的例子
import numpy as np
arr=np.array([[1],[2],[3],[4]])
a=dict()
# Adding the first element from the array as a dictionary key
a[arr[0]]= "Value"
输出
Traceback (most recent call last):
File "C:\Users\paian\PycharmProjects\Finxter\venv\share\unhashable_type_ndarray.py", line 5, in <module>
a[arr[0]]= "Value"
TypeError: unhashable type: 'numpy.ndarray'
我们看到一个错误,因为arr[0] 是[1] ,它是一个 ndarray 对象 (不可哈希的类型)
修复
为了解决这个问题,正确地对内部元素进行索引,如下图所示。
import numpy as np
arr=np.array([[1],[2],[3],[4]])
a=dict()
# Adding the first element from the array as a dictionary key
a[arr[0,0]]= "Value"
print(a)
输出
{1: 'Value'}
案例3:将ndarray对象添加到一个集合中
集合对象只能包含可散列的元素。如果你添加任何不可哈希的对象类型作为集合元素,你会看到一个错误。
例子
让我们看看如果有一个数组[1,2,3,4] ,你想把这个数组的所有元素添加到一个集合中会发生什么。
import numpy as np
arr=np.array([1,2,3,4])
a=set()
a.add(arr)
输出
Traceback (most recent call last):
File "C:\Users\...\unhashable_type_ndarray.py", line 5, in <module>
a.add(arr)
TypeError: unhashable type: 'numpy.ndarray'
我们看到一个错误,因为我们添加了数组对象而不是它的元素在 [set.add()](https://blog.finxter.com/python-set-add/)函数中添加数组对象而不是它的元素。
修复
为了解决这个问题,添加数组的元素而不是数组对象,如下图所示。
import numpy as np
arr=np.array([1,2,3,4])
a=set()
for ele in arr:
a.add(ele)
print(a)
输出:要解决这个问题,需要添加数组的元素,而不是数组对象,如下图所示
{1, 2, 3, 4}
结论
我们已经到了这篇文章的结尾。我希望这篇文章能提供一些信息。