Uma das estruturas básicas de dados no Python é o dicionário, que permite registrar "chaves" para procurar "valores" de qualquer tipo. Isso é implementado internamente como uma tabela de hash? se não, o que é?
Uma das estruturas básicas de dados no Python é o dicionário, que permite registrar "chaves" para procurar "valores" de qualquer tipo. Isso é implementado internamente como uma tabela de hash? se não, o que é?
Respostas:
Sim, é um mapeamento de hash ou tabela de hash. Você pode ler uma descrição da implementação de dict do python, conforme escrito por Tim Peters, aqui .
É por isso que você não pode usar algo 'não lavável' como uma chave de dict, como uma lista:
>>> a = {}
>>> b = ['some', 'list']
>>> hash(b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list objects are unhashable
>>> a[b] = 'some'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list objects are unhashable
Você pode ler mais sobre tabelas de hash ou verificar como elas foram implementadas em python e por que são implementadas dessa maneira .
.keys()
pode recuperar uma lista de chaves. Uma tabela de hash real não armazena chaves, apenas hashes para economizar espaço.
Deve haver mais em um dicionário Python do que uma pesquisa de tabela em hash (). Por experimentação bruta, encontrei esta colisão de hash :
>>> hash(1.1)
2040142438
>>> hash(4504.1)
2040142438
No entanto, não quebra o dicionário:
>>> d = { 1.1: 'a', 4504.1: 'b' }
>>> d[1.1]
'a'
>>> d[4504.1]
'b'
Verificação de sanidade:
>>> for k,v in d.items(): print(hash(k))
2040142438
2040142438
Possivelmente, existe outro nível de pesquisa além do hash () que evita colisões entre as chaves do dicionário. Ou talvez dict () use um hash diferente.
(A propósito, isso no Python 2.7.10. A mesma história no Python 3.4.3 e 3.5.0 com uma colisão em hash(1.1) == hash(214748749.8)
.)
hash('I wandered lonely as a cloud, that drifts on high o\'er vales and hills, when all at once, I saw a crowd, a host of golden daffodils.')
Isso fornece um decimal de 19 dígitos - -4037225020714749784
se você é nerd o suficiente para se importar. Continue com suas próprias palavras, crianças, e o hash ainda é um número de 19 dígitos. Suponho que exista um limite no comprimento da string que você pode fazer hash no Python, mas é seguro dizer muito mais strings possíveis do que valores possíveis. E hash(False)
= 0 por sinal.
Sim. Internamente, é implementado como hash aberto com base em um polinômio primitivo sobre Z / 2 ( fonte ).
Para expandir a explicação de nosklo:
a = {}
b = ['some', 'list']
a[b] = 'some' # this won't work
a[tuple(b)] = 'some' # this will, same as a['some', 'list']
dict
implementação do Python .