开放的编程资料库

当前位置:我爱分享网 > Python教程 > 正文

Python哈希

Python哈希教程解释了Python中的哈希概念。我们解释了哈希表和Python可哈希对象。

哈希表

哈希表用于在许多常见的编程语言(例如C++、Java和Python)中实现映射和集合数据结构。Python对字典和集合使用哈希表。哈希表是键值对的无序集合,其中每个键都是唯一的。哈希表提供了高效查找、插入和删除操作的组合。这些是数组和链表的最佳属性。

散列

Hashing是使用算法将任意大小的数据映射到固定长度的过程。这称为散列值。散列用于创建高性能、直接访问的数据结构,其中大量数据将被快速存储和访问。哈希值是用哈希函数计算的。

Python可哈希

如果一个对象的哈希值在其生命周期内永不改变,则该对象是可哈希的。(在多次调用Python程序期间它可以有不同的值。)可散列对象需要一个__hash__方法。为了执行比较,可散列需要一个__eq__方法。

可哈希性使对象可用作字典键和集合成员,因为这些数据结构在内部使用哈希值。Python不可变内置对象是可散列的;可变容器(例如列表或字典)不是。默认情况下,作为用户定义类实例的对象是可散列的。它们都比较不相等(除了它们自己),它们的哈希值是从它们的id派生的。

Pythonhash()函数

hash函数返回对象的散列值(如果有的话)。散列值是整数。它们用于在字典查找期间快速比较字典键。对象可以实现__hash__方法。

Python不可变内置函数是可哈希的

Python不可变内置函数(例如整数、字符串或元组)是可哈希的。

#!/usr/bin/python

val = 100

print(val.__hash__())
print("falcon".__hash__())
print((1,).__hash__())

该示例打印了三个可哈希值的值:一个整数、一个字符串和一个元组。

Python自定义哈希示例I

默认情况下,Python自定义对象是可哈希的。他们的散列是从他们的Id派生的。

#!/usr/bin/python

class User:

    def __init__(self, name, occupation):

        self.name = name
        self.occupation = occupation

u1 = User('John Doe', 'gardener')
u2 = User('John Doe', 'gardener')

print('hash of user 1')
print(hash(u1))

print('hash of user 2')
print(hash(u2))

if (u1 == u2):
    print('same user')
else:
    print('different users')

在示例中,我们有两个User实例。

u1 = User('John Doe', 'gardener')
u2 = User('John Doe', 'gardener')

我们有两个具有相同数据的实例。

print('hash of user 1')
print(hash(u1))

hash函数返回对象的哈希值。默认实现是从对象的Id派生的。

$ python custom_object.py
hash of user 1
-9223371894419573195
hash of user 2
142435202673
different users

即使用户详细信息相同,比较也会产生不同的对象。为了改变它,我们需要实现__eq__方法。

Python自定义哈希示例II

在第二个例子中,我们实现了一个自定义的__eq__方法。

#!/usr/bin/python

class User:

    def __init__(self, name, occupation):

        self.name = name
        self.occupation = occupation

    def __eq__(self, other):

        return self.name == other.name \
            and self.occupation == other.occupation

    def __str__(self):
        return f'{self.name} {self.occupation}'


u1 = User('John Doe', 'gardener')
u2 = User('John Doe', 'gardener')

if (u1 == u2):
    print('same user')
    print(f'{u1} == {u2}')
else:
    print('different users')

# users = {u1, u2}
# print(len(users))

现在比较返回我们预期的输出;但是,我们不能将对象插入到Python集合中;它会导致TypeError:unhashabletype:'User'。为了改变这一点,我们实现了__hash__方法。

Python自定义哈希示例III

在第三个示例中,我们实现了__eq____hash__方法。

#!/usr/bin/python

class User:

    def __init__(self, name, occupation):

        self.name = name
        self.occupation = occupation

    def __eq__(self, other):

        return self.name == other.name \
            and self.occupation == other.occupation

    def __hash__(self):
        return hash((self.name, self.occupation))

    def __str__(self):
        return f'{self.name} {self.occupation}'


u1 = User('John Doe', 'gardener')
u2 = User('John Doe', 'gardener')

users = {u1, u2}

print(len(users))

if (u1 == u2):
    print('same user')
    print(f'{u1} == {u2}')
else:
    print('different users')

print('------------------------------------')

u1.occupation = 'programmer'

users = {u1, u2}

print(len(users))

if (u1 == u2):
    print('same user')
    print(f'{u1} == {u2}')
else:
    print('different users')

该示例比较了两个具有__eq____hash__方法的自定义实现的对象。可以将这些对象插入到Python集合中,当属性稍后更改时,我们得到预期的输出。

def __hash__(self):
    return hash((self.name, self.occupation))

__hash__函数的实现返回使用hash函数从属性元组计算的哈希值。

$ python custom_object3.py
1
same user
John Doe gardener == John Doe gardener
------------------------------------
2
different users

Python@dataclass装饰器

从Python3.7开始,我们有了dataclass装饰器,它会自动生成一些样板代码。

数据类装饰器有一个冻结参数(默认为False)。如果指定,字段将被冻结(即只读)。如果eq设置为True,这是默认设置,那么__hash__方法将被实现并且对象实例将是可散列的。

#!/usr/bin/python

from dataclasses import dataclass

@dataclass(frozen=True)
class User:

    name: str
    occupation: str


u1 = User('John Doe', 'gardener')
u2 = User('John Doe', 'gardener')

if (u1 == u2):
    print('same user')
    print(f'{u1} == {u2}')
else:
    print('different users')

users = {u1, u2}
print(len(users))

该示例使用了@dataclass装饰器。

$ python decorator.py
same user
User(name='John Doe', occupation='gardener') == User(name='John Doe', occupation='gardener')
1

在本教程中,我们介绍了Python中的散列。

列出所有Python教程。

未经允许不得转载:我爱分享网 » Python哈希

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏