L'objet 'dict' n'a pas d'attribut 'has_key'

105

En parcourant un graphique en Python, je reçois cette erreur:

L'objet 'dict' n'a pas d'attribut 'has_key'

Voici mon code:

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

Le code vise à trouver les chemins d'un nœud à d'autres. Source du code: http://cs.mwsu.edu/~terry/courses/4883/lectures/graphs.html

Pourquoi est-ce que j'obtiens cette erreur et comment puis-je la corriger?

Ashi
la source
2
if not start in graph:
Peter Wood
1
Possible duplication de 'has_key ()' ou 'in'?
Peter Wood

Réponses:

180

has_keya été supprimé dans Python 3. De la documentation :

  • Supprimé dict.has_key()- utilisez inplutôt l' opérateur.

Voici un exemple:

if start not in graph:
    return None
johnnyRose
la source
1
Je pense que key not in d.keys()c'est probablement beaucoup plus lent aussi, car key not in ddevrait être une recherche O (1) et je crois qu'elle keysproduit une liste, qui est une recherche O (n) (sans parler de la prise d'espace supplémentaire en mémoire). Je pourrais me tromper à ce sujet - il pourrait encore s'agir d'une recherche hachée
Adam Smith
3
@AdamSmith pas dans Python 3, d.keys()est une vue qui implémente la plupart de l'interface définie.
Antti Haapala
3
Il a été supprimé ... mais pourquoi? Puisqu'il rend le portage de python 2 vers python 3 plus de travail à faire.
Fruit
1
@ 林果 皞: L'intérêt d'une nouvelle version majeure est que les développeurs peuvent introduire des améliorations qui peuvent inclure des changements de rupture au lieu d'avoir à supporter d'anciennes fonctionnalités à mesure que le langage évolue. Il s'agit toujours d'un risque qui doit être pris en compte avant de passer à une nouvelle version majeure. Dans ce cas, inest plus court et plus pythonique, tout en étant cohérent avec d'autres collections de la langue.
johnnyRose
23

has_key est obsolète dans Python 3.0 . Vous pouvez également utiliser «in»

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

print('A' in graph)
>> True

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

En python3, has_key(key)est remplacé par__contains__(key)

Testé en python3.7:

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

Je pense qu'il est considéré comme "plus pythonique" de l'utiliser uniquement inpour déterminer si une clé existe déjà, comme dans

if start not in graph:
    return None
Kevin S
la source
Je ne suis pas sûr, selon The Zen of Python (PEP 20): "Explicite vaut mieux qu'implicite". Je pense que si vous utilisez le inmot - clé, votre intention n'est peut-être pas assez claire. Qu'est-ce que cela if start not in graph:signifie? peut être graphest une liste et il vérifie s'il n'y a pas une telle chaîne dans la liste? D'autre part, si vous utilisez une syntaxe comme has_key(maintenant obsolète) ou du moins, in graph.keys()il est plus clair que graphc'estdict
Amitay Drummer
4

L'ensemble du code du document sera:

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

Après l'avoir écrit, enregistrez le document et appuyez sur F 5

Après cela, le code que vous exécuterez dans le shell Python IDLE sera:

find_path (graphique, 'A', 'D')

La réponse que vous devriez recevoir dans IDLE est

['A', 'B', 'C', 'D'] 
Oana Roxana
la source
Pouvez-vous l'expliquer, en particulier la partie récursivité.
Chiffrer
2

Essayer:

if start not in graph:

Pour plus d'informations, voir ProgrammerSought

Mo-Gang
la source