O que é um hash e como é usado nos dicionários em Python?
sobes.tech IA
Resposta da IA
Hash (ou valor de hash) é um valor numérico de comprimento fixo calculado com base no conteúdo de um objeto através de uma função de hash. Uma boa função de hash garante a deterministicidade (o mesmo objeto sempre fornece o mesmo hash) e busca uma distribuição uniforme dos hashes para diferentes objetos.
Em Python, os dicionários (tipo dict) usam hashing para armazenar e procurar eficientemente pares de "chave-valor". As chaves devem ser hasháveis, ou seja, possuir o método __hash__() e serem imutáveis ou ter uma implementação de __eq__() e __hash__() que garanta que objetos iguais por __eq__ tenham o mesmo hash.
Processo de funcionamento de um dicionário com hashes:
- Inserção: Ao adicionar um par (chave, valor), o hash da chave é calculado. Com base no hash, é determinado um local aproximado (cesto ou "bucket") para armazenar esse par na memória. Se várias chaves tiverem o mesmo hash (colisão), os pares são armazenados nesse cesto, frequentemente em forma de lista ligada ou outro mecanismo de resolução de colisões.
- Busca: Ao procurar um valor por chave, o hash da chave fornecida é calculado. Usando o hash, o dicionário encontra rapidamente o cesto correspondente. Depois, dentro desse cesto, ocorre uma comparação das chaves (usando o método
__eq__) para encontrar a chave correta e extrair seu valor associado.
Vantagens do uso de hashing:
- Eficiência: Em média, as operações de inserção, remoção e busca em um dicionário são realizadas com uma complexidade de tempo constante O(1), independentemente do tamanho do dicionário.
- Acesso rápido: O hash permite acessar rapidamente a localização prevista dos dados, evitando percorrer todos os elementos.
Restrições e características:
- Chaves hasháveis: Como mencionado, as chaves devem ser hasháveis. Tipos mutáveis, como listas (
list) e conjuntos (set), não são hasháveis por padrão e não podem ser usados como chaves de dicionário. - Colisões: Embora as funções de hash tentem minimizar colisões, elas podem ocorrer, o que pode desacelerar um pouco as operações no pior caso (afetando a constante em O(1)).
- Ordem: Até Python 3.7, a ordem dos elementos em um dicionário dependia da ordem de inserção e dos hashes das chaves. A partir do Python 3.7, os dicionários mantêm a ordem de inserção das chaves como um efeito secundário da implementação, mas isso não faz parte do mecanismo de hashing.
Exemplo de um objeto hashable e não hashable:
# Objeto hashable (imutável)
string_key = "hello"
int_key = 123
tuple_key = (1, 2)
print(hash(string_key))
print(hash(int_key))
print(hash(tuple_key))
# Objeto não hashable (mutável)
list_key = [1, 2]
# print(hash(list_key)) # Isto causará um TypeError
# Exemplo de uso em um dicionário
my_dict = {
string_key: "mundo",
int_key: 456,
tuple_key: "uma tupla"
}
print(my_dict[string_key])
print(my_dict[int_key])
print(my_dict[tuple_key])
Assim, o hash é um mecanismo fundamental que permite aos dicionários em Python alcançar alta performance nas operações, baseado no cálculo rápido da representação numérica da chave.