El objeto 'dict' no tiene atributo 'has_key'

105

Al recorrer un gráfico en Python, recibo este error:

El objeto 'dict' no tiene atributo 'has_key'

Aquí está mi 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

El código tiene como objetivo encontrar las rutas de un nodo a otros. Fuente del código: http://cs.mwsu.edu/~terry/courses/4883/lectures/graphs.html

¿Por qué recibo este error y cómo puedo solucionarlo?

Ashi
fuente
2
if not start in graph:
Peter Wood
1
¿Posible duplicado de 'has_key ()' o 'in'?
Peter Wood

Respuestas:

180

has_keyfue eliminado en Python 3. De la documentación :

  • Eliminado dict.has_key(): utilice el inoperador en su lugar.

He aquí un ejemplo:

if start not in graph:
    return None
JohnnyRose
fuente
1
Creo que key not in d.keys()probablemente también sea mucho más lento, ya que key not in ddebería ser una búsqueda O (1) y creo que keysproduce una lista, que es una búsqueda O (n) (sin mencionar que ocupa espacio adicional en la memoria). Sin embargo, podría estar equivocado en eso, podría ser una búsqueda hash
Adam Smith
3
@AdamSmith no está en Python 3, d.keys()es una vista que implementa la mayor parte de la interfaz establecida.
Antti Haapala
3
Se quitó ... pero ¿por qué? Ya que hace que Python 2 se adapte a Python 3, más trabajo por hacer
Fruta
1
@ 林果 皞: El objetivo de una nueva versión principal es que los desarrolladores pueden introducir mejoras que pueden incluir cambios importantes en lugar de tener que admitir características antiguas a medida que el lenguaje madura. Este es siempre un riesgo que debe tenerse en cuenta antes de actualizar a una nueva versión principal. En este caso, ines más corto y más pitónico, además de ser coherente con otras colecciones del idioma.
johnnyRose
23

has_key ha quedado obsoleto en Python 3.0 . Alternativamente, puede usar 'en'

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

print('A' in graph)
>> True

print('E' in graph)
>> False
Abhishek Pansotra
fuente
17

En python3, has_key(key)se reemplaza por__contains__(key)

Probado en python3.7:

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

Creo que se considera "más pitónico" usarlo inpara determinar si una clave ya existe, como en

if start not in graph:
    return None
Kevin S
fuente
No estoy seguro, según The Zen of Python (PEP 20): "Explícito es mejor que implícito". Creo que si usa la inpalabra clave, su intención podría no ser lo suficientemente clara, ¿qué if start not in graph:significa? puede ser graphuna lista y verifica si no hay tal cadena en la lista? Por otro lado, si usa una sintaxis como has_key(ahora en desuso) o al menos in graph.keys()está más claro que graphes undict
Amitay Drummer
4

El código completo en el 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

Después de escribirlo, guarde el documento y presione F 5

Después de eso, el código que ejecutará en el shell de Python IDLE será:

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

La respuesta que debe recibir en IDLE es

['A', 'B', 'C', 'D'] 
Oana Roxana
fuente
¿Puede explicarlo? Específicamente la parte de recursividad.
Encipher