222

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?

1

6 Answers 6

329

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
Sign up to request clarification or add additional context in comments.

4 Comments

I think key not in d.keys() is probably much slower, too, since key not in d should be O(1) lookup and I believe keys 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 lookup
@AdamSmith not in Python 3, d.keys() is a view that implements most of the set interface.
It removed... but why ? Since it make python 2 port to python 3 more work to do.
@林果皞: The whole point of a new major version is that the developers can introduce improvements which may include breaking changes instead of having to support old features as the language matures. This is always a risk which must be considered before upgrading to a new major version. In this case, in is shorter and more Pythonic, as well as being consistent with other collections in the language.
70

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

2 Comments

I think this is the right and easier way to do, Thank you for the answer
No, no, no... the __contains__() method is how you implement a containment test in a user-defined class, the in operator is how you actually use that test. About the only time you should ever explicitly call a double-underscored "magic" method is in a subclass method, as part of calling the superclass implementation.
34

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

Comments

9

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

1 Comment

I'm not sure, according to The Zen of Python(PEP 20): "Explicit is better than implicit". I think that if you use the 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
7

Try:

if start not in graph:

For more info see ProgrammerSought

Comments

4

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

1 Comment

Can you please explain it ?specifically the recursion portion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.