O objeto 'dict' não tem atributo 'has_key'


105

Ao percorrer um gráfico em Python, recebo este erro:

O objeto 'dict' não tem atributo 'has_key'

Aqui está o meu código:

def find_path(graph, start, end, path=[]):
    path = path + [start]
    if start == end:
        return path
    if not graph.has_key(start):
        return None
    for node in graph[start]:
        if node not in path:
            newpath = find_path(graph, node, end, path)
            if newpath: return newpath
    return None

O código visa encontrar os caminhos de um nó para outros. Fonte do código: http://cs.mwsu.edu/~terry/courses/4883/lectures/graphs.html

Por que estou recebendo esse erro e como posso corrigi-lo?


2
if not start in graph:
Peter Wood

1
Possível duplicata de 'has_key ()' ou 'in'?
Peter Wood

Respostas:


180

has_keyfoi removido do Python 3. Da documentação :

  • Removido dict.has_key()- use o inoperador.

Aqui está um exemplo:

if start not in graph:
    return None

1
Acho que key not in d.keys()é provavelmente muito mais lento também, já que key not in ddeve ser O (1) lookup e acredito que keysproduz uma lista, que é O (n) lookup (sem mencionar que ocupa espaço extra na memória). Posso estar errado sobre isso - ainda pode ser uma pesquisa hash
Adam Smith

3
@AdamSmith não em Python 3, d.keys()é uma visão que implementa a maior parte da interface definida.
Antti Haapala

3
Ele removeu ... mas por quê? Uma vez que isso torna a porta do python 2 para o python 3 mais trabalho a fazer.
Frutas de

1
@ 林果 皞: O ponto principal de uma nova versão principal é que os desenvolvedores podem introduzir melhorias que podem incluir mudanças significativas em vez de ter que suportar recursos antigos conforme a linguagem amadurece. Este é sempre um risco que deve ser considerado antes de atualizar para uma nova versão principal. Neste caso, iné mais curto e pitônico, além de ser consistente com outras coleções do idioma.
johnnyRose

23

has_key tornou-se obsoleto no Python 3.0 . Alternativamente, você pode usar 'em'

graph={'A':['B','C'],
   'B':['C','D']}

print('A' in graph)
>> True

print('E' in graph)
>> False

17

Em python3, has_key(key)é substituído por__contains__(key)

Testado em python3.7:

a = {'a':1, 'b':2, 'c':3}
print(a.__contains__('a'))

5

Acho que é considerado "mais pitônico" apenas para usar inao determinar se uma chave já existe, como em

if start not in graph:
    return None

Não tenho certeza, de acordo com The Zen of Python (PEP 20): "Explícito é melhor do que implícito". Eu acho que se você usar a inpalavra - chave, sua intenção pode não ser clara o suficiente o que if start not in graph:significa? pode ser graphé uma lista e verifica se não existe tal string na lista? Por outro lado, se você usa sintaxe como has_key(agora obsoleta) ou pelo menos in graph.keys()é mais claro que graphé umdict
Amitay Drummer

4

Todo o código do documento será:

graph = {'A': ['B', 'C'],
             'B': ['C', 'D'],
             'C': ['D'],
             'D': ['C'],
             'E': ['F'],
             'F': ['C']}
def find_path(graph, start, end, path=[]):
        path = path + [start]
        if start == end:
            return path
        if start not in graph:
            return None
        for node in graph[start]:
            if node not in path:
                newpath = find_path(graph, node, end, path)
                if newpath: return newpath
        return None

Depois de escrever, salve o documento e pressione F 5

Depois disso, o código que você executará no shell Python IDLE será:

find_path (gráfico, 'A', 'D')

A resposta que você deve receber no IDLE é

['A', 'B', 'C', 'D'] 

Você pode explicar especificamente a parte da recursão.
Codificar

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.