'dict'オブジェクトには属性 'has_key'がありません


104

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:
Peter Wood

回答:


180

has_keyPython 3で削除されました。ドキュメントから:

  • 削除済みdict.has_key()in代わりに演算子を使用してください。

次に例を示します。

if start not in graph:
    return None

1
O(1)ルックアップである必要があるので、key not in d.keys()おそらくかなり遅くなると思いますkey not in d。O keys(n)ルックアップであるリストを生成すると思います(メモリに余分なスペースをとるのは言うまでもありません)。私はそれについて間違っているかもしれません-それはまだハッシュされたルックアップかもしれません
Adam Smith

3
Python 3にd.keys()はない@AdamSmith は、設定されたインターフェースのほとんどを実装するビューです。
Antti Haapala 2017年

3
それは削除されました...しかし、なぜですか?それはpython 2からpython 3への移植を行うので、さらに多くの作業が必要になります。
フルーツ

1
@林果皞:新しいメジャーバージョンの要点は、言語が成熟するにつれて古い機能をサポートする必要がなく、変更を壊すなどの改善を開発者が導入できることです。これは常にリスクであり、新しいメジャーバージョンにアップグレードする前に考慮する必要があります。この場合、inはより短く、よりPythonicであるだけでなく、言語内の他のコレクションとも一致しています。
johnnyRose 2018

23

has_keyPython 3.0で廃止されました。または、「in」を使用できます

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

print('A' in graph)
>> True

print('E' in graph)
>> False

17

python3では、has_key(key)置き換えられます__contains__(key)

python3.7でテスト:

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

5

次のようにin、キーがすでに存在するかどうかを判断するときに使用することは、「よりpythonic」と見なされていると思います

if start not in graph:
    return None

The Zen of Python(PEP 20)によると、「はっきりしていませんが、明示的である方がよい」と私は確信していません。inキーワードを使うと意図がはっきりしないのではないif start not in graph:でしょうか?graphリストである可能性があり、リストにそのような文字列がないかどうかをチェックしますか?一方、has_key(現在は非推奨)などの構文を使用している場合、または少なくともin graph.keys()それがより明確でgraphある場合dict
Amitay Drummer

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'] 

具体的には、再帰部分について説明してください。
暗号化

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.