Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the dict.keys not iterable?

Tags:

python

node_name is a string. Shouldn't this return a list of keys in the node_list dictionary, which can be iterated over? Why does the error say it is not iterable?

class Graph:

def __init__(self):
    self.node_list = {}
    self.number = 0

def node(self, node_name):
    if node_name in self.node_list.keys: 
    ...

File "PythonProject2.3.py", line 10, in node
    if node_name in self.node_list.keys: #returns list of keys
TypeError: argument of type 'builtin_function_or_method' is not iterable
like image 888
jukhamil Avatar asked Oct 28 '25 18:10

jukhamil


2 Answers

.keys is a function, not a property. Try this instead:

if node_name in self.node_list.keys():

A dictionary iterates over its keys by default, though, so this will work, too:

if node_name in self.node_list:
like image 103
mipadi Avatar answered Oct 31 '25 08:10

mipadi


Python sees node_name in self.node_list.keys, so it evaluates self.node_list.keys and then tries to work out whether or not node_name is in the result of that.

self.node_list.keys is a function (you should have written keys()), but all that's really relevant here is that it doesn't support the Python in operator. That is to say, you can't test whether or not something is in self.node_list.keys.

The reason you specifically get an error about iteration, is that Python first checks for the __contains__ function and, if not present, tries to iterate over the right-hand operand of in comparing each value against the left-operand using ==. This fails, hence the exception you saw. The reason Python does that is just so that anything which supports iteration also supports in automatically. Albeit perhaps not very efficiently.

like image 31
Steve Jessop Avatar answered Oct 31 '25 07:10

Steve Jessop