объект 'dict' не имеет атрибута 'has_key'

108

При просмотре графика в Python я получаю следующую ошибку:

объект 'dict' не имеет атрибута 'has_key'

Вот мой код:

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

Код нацелен на поиск путей от одного узла к другому. Источник кода: http://cs.mwsu.edu/~terry/courses/4883/lectures/graphs.html

Почему я получаю эту ошибку и как ее исправить?

Аши
источник
2
if not start in graph:
Питер Вуд
1
Возможный дубликат has_key () или in?
Питер Вуд

Ответы:

182

has_keyбыл удален в Python 3. Из документации :

  • Удалено dict.has_key()- используйте inвместо этого оператор.

Вот пример:

if start not in graph:
    return None
Джонни Роуз
источник
1
Я думаю, что key not in d.keys()это, вероятно, намного медленнее, поскольку key not in dдолжен быть поиск O (1), и я считаю, что keysсоздает список, который является поиском O (n) (не говоря уже о дополнительном пространстве в памяти). Хотя я могу ошибаться - это все еще может быть хешированный поиск
Адам Смит
3
@AdamSmith не в Python 3, d.keys()это представление, которое реализует большую часть установленного интерфейса.
Антти Хаапала
3
Его сняли ... но почему? Поскольку он делает перенос с Python 2 на Python 3, нужно сделать больше.
Fruit
1
@ 林果 皞: Вся суть новой основной версии заключается в том, что разработчики могут вносить улучшения, которые могут включать критические изменения, вместо необходимости поддерживать старые функции по мере развития языка. Это всегда риск, который необходимо учитывать перед обновлением до новой основной версии. В этом случае inон короче и более Pythonic, а также согласуется с другими коллекциями на языке.
johnnyRose
23

has_key устарел в Python 3.0 . В качестве альтернативы вы можете использовать 'in'

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

print('A' in graph)
>> True

print('E' in graph)
>> False
Абхишек Пансотра
источник
18

В python3 has_key(key)заменяется на__contains__(key)

Протестировано в python3.7:

a = {'a':1, 'b':2, 'c':3}
print(a.__contains__('a'))
Кловешмили
источник
5

Я думаю, что "более питоническим" считается использование inпри определении того, существует ли уже ключ, как в

if start not in graph:
    return None
Кевин С
источник
Я не уверен, согласно «Дзену Python» (PEP 20): «Явное лучше, чем неявное». Я думаю, что если вы используете inключевое слово, ваше намерение может быть недостаточно ясным, что if start not in graph:означает? может быть graphэто список и он проверяет, нет ли такой строки в списке? С другой стороны, если вы используете синтаксис вроде has_key(теперь устарел) или, по крайней мере, in graph.keys()более ясно, что graphэтоdict
Амитай Барабанщик
4

Весь код в документе будет:

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

После написания сохраните документ и нажмите F 5

После этого код, который вы запустите в оболочке Python IDLE, будет следующим:

find_path (график, 'A', 'D')

Ответ, который вы должны получить в IDLE:

['A', 'B', 'C', 'D'] 
Оана Роксана
источник
Не могли бы вы объяснить это, в частности, часть рекурсии.
Encipher 07
3

Пытаться:

if start not in graph:

Для получения дополнительной информации см. ProgrammerSought.

Mo-Gang
источник