length of the values of any given key

Question:

I am trying to create a function that will return the degrees of a given node in a graph. I keep running into the error unhashable type: ‘list’ in my degree function and I’m not really sure why this is happening since I am not trying to assign a list as a key, which is what causes this error as far as I understand. All I need to do is get the length of the values for any given key I input into degree. I feel like I’m missing something obvious but I’ve been staring at this long enough to lose my mind and would appreciate a fresh set of eyes.

from collections import defaultdict
graph = defaultdict(dict)

def addEdge(node1, node2): #adds edges to the graph
    # create an empty list for a key node
    if node1 not in graph:
        graph[node1] = []
    if node2 not in graph:
        graph[node2] = []
    graph[node1].append(node2) #adds the edges to each other
    graph[node2].append(node1)

def degree(node):
  for node in graph.items(): 
    degrees = len(graph[node])
    return degrees

def select():
  weights = []
  for i in graph:
    weights.append(degree(i))
    
Asked By: slacks37

||

Answers:

The problem I see with your code is here:

for node in graph.items(): 
    degrees = len(graph[node])

You are iterating over each value returned by graph.items(), treating each one as though it is a key in your graph dictionary. You expect that iterating on graph.items() gives you each of the nodes in graph. That’s not what it does. items() returns a tuple containing both the key and the value for each item in the dictionary. The second item in each of those tuples is a list.
That’s the list that the error message is complaining about. What I think you mean to do is iterate over the keys in graph. Replacing graph.items() with graph.keys() should resolve your problem:

for node in graph.keys(): 
    degrees = len(graph[node])

I see two other problems…

Your degree function takes node as a parameter, but you use that same variable name in your iteration. So the parameter you’re passing to degree isn’t being used.

Another problem I see is that the overall logic in the degree function makes no sense. You start to iterate over the items in graph, but then you return from the function at the end of the first iteration. So you aren’t really iterating. Maybe your indentation is wrong and your return statement should only execute after all iterations have happened. But then you’re setting degrees over and over, so your iterations are happening, but only the last one has any affect.

In select, you’re already iterating over graph. So what I’m guessing you want is to not have a for loop in degree, but rather just have that function return the length of the list associated with the passed in node. So I think degree should really be:

def degree(node):
    return len(graph[node])
Answered By: CryptoFool
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.