L'oggetto "dict" non ha attributo "has_key"


105

Durante l'attraversamento di un grafico in Python, ricevo questo errore:

L'oggetto "dict" non ha attributo "has_key"

Ecco il mio codice:

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

Il codice mira a trovare i percorsi da un nodo ad altri. Fonte del codice: http://cs.mwsu.edu/~terry/courses/4883/lectures/graphs.html

Perché ricevo questo errore e come posso risolverlo?


2
if not start in graph:
Peter Wood

1
Possibile duplicato di "has_key ()" o "in"?
Peter Wood

Risposte:


180

has_keyè stato rimosso in Python 3. Dalla documentazione :

  • Rimosso dict.has_key(): usa ininvece l' operatore.

Ecco un esempio:

if start not in graph:
    return None

1
Penso che key not in d.keys()sia probabilmente anche molto più lento, poiché key not in ddovrebbe essere la ricerca O (1) e credo che keysproduca una lista, che è la ricerca O (n) (per non parlare dell'occupazione di spazio extra in memoria). Potrei sbagliarmi su questo però - potrebbe ancora essere una ricerca con hash
Adam Smith

3
@AdamSmith non in Python 3, d.keys()è una vista che implementa la maggior parte dell'interfaccia impostata.
Antti Haapala

3
Ha rimosso ... ma perché? Dal momento che rende il port di python 2 su python 3 più lavoro da fare.
Frutta l'

1
@ 林果 皞: Il punto centrale di una nuova versione principale è che gli sviluppatori possono introdurre miglioramenti che possono includere modifiche sostanziali invece di dover supportare vecchie funzionalità man mano che la lingua matura. Questo è sempre un rischio che deve essere considerato prima di eseguire l'aggiornamento a una nuova versione principale. In questo caso inè più breve e più pitonico, oltre ad essere coerente con altre raccolte nella lingua.
johnnyRose

23

has_key è stato deprecato in Python 3.0 . In alternativa puoi usare "in"

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

print('A' in graph)
>> True

print('E' in graph)
>> False

17

In python3, has_key(key) è sostituito da__contains__(key)

Testato in python3.7:

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

5

Penso che sia considerato "più pitonico" da usare solo inper determinare se una chiave esiste già, come in

if start not in graph:
    return None

Non sono sicuro, secondo The Zen of Python (PEP 20): "Explicit is better than implicit". Penso che se usi la inparola chiave, la tua intenzione potrebbe non essere abbastanza chiara cosa if start not in graph:significa? può essere graphè una lista e controlla se non c'è una stringa di questo tipo nella lista? D'altra parte, se usi una sintassi come has_key(ora deprecata) o almeno in graph.keys()è più chiaro che graphè undict
Amitay Drummer

4

L'intero codice nel documento sarà:

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

Dopo averlo scritto, salva il documento e premi F 5

Dopodiché, il codice che eseguirai nella shell IDLE di Python sarà:

find_path (grafico, 'A', 'D')

La risposta che dovresti ricevere in IDLE è

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

Puoi spiegarlo per favore? In particolare la parte della ricorsione.
Cifra

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.