While traversing a graph in Python, a I'm receiving this error:
'dict' object has no attribute 'has_key'
Here is my 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
The code aims to find the paths from one node to others. Code source: http://cs.mwsu.edu/~terry/courses/4883/lectures/graphs.html
Why am I getting this error and how can I fix it?
has_key
was removed in Python 3. From the documentation:
Removed dict.has_key() – use the in operator instead.
Here's an example:
if start not in graph:
return None
In python3, has_key(key)
is replaced by __contains__(key)
Tested in python3.7:
a = {'a':1, 'b':2, 'c':3}
print(a.__contains__('a'))
has_key has been deprecated in Python 3.0. Alternatively you can use 'in'
graph={'A':['B','C'],
'B':['C','D']}
print('A' in graph)
>> True
print('E' in graph)
>> False
I think it is considered "more pythonic" to just use in
when determining if a key already exists, as in
if start not in graph:
return None
in
keyword, your intention might not be clear enough what does if start not in graph:
means? may be graph
is a list and it checks if there is no such string in the list? On the other hand, if you use syntax like has_key
(now deprecated) or at least in graph.keys()
it is more clear that graph
is a dict
The whole code in the document will be:
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
After writing it, save the document and press F 5
After that, the code you will run in the Python IDLE shell will be:
find_path(graph, 'A','D')
The answer you should receive in IDLE is
['A', 'B', 'C', 'D']
Success story sharing
key not in d.keys()
is probably much slower, too, sincekey not in d
should be O(1) lookup and I believekeys
produces a list, which is O(n) lookup (not to mention taking extra space in memory). I could be wrong about that though -- it might still be hashed lookupd.keys()
is a view that implements most of the set interface.in
is shorter and more Pythonic, as well as being consistent with other collections in the language.