Reputation: 199
I am new to python and I am trying to do the following:
x
sequentially from a list randomnodes
and append the neighbors of x
at the end of the list.The code I have written is given below:
for x in randomnodes:
if len(randomnodes)<=100:
randomnodes.append(neighbors(x))
where neighbors(x) returns a list.
But the code gives an error:
Traceback (most recent call last):
File "randomsampling_diameter.py", line 48, in <module>
randomnodes.append(neighbors(x))
File "/usr/local/lib/python2.7/dist-packages/networkx-1.9.1-py2.7.egg/networkx/classes/graph.py", line 980, in neighbors
return list(self.adj[n])
TypeError: unhashable type: 'list'
Why is it so? How should the code be modified to achieve the task?
Upvotes: 2
Views: 2636
Reputation: 104762
The trouble you're having is that you're adding the neighbors list to the end of randomnodes
, rather than adding elements from the list. This leads a later iteration to try to get the neighbors of the nested neighbor list, resulting in an exception.
If you don't mind the randomnodes
list sometimes getting a few extra elements, you could just replace append
with extend
in your current code.
Otherwise, try this slightly more complicated code that uses list.extend
to add an appropriate number elements from the neighbor list to randomnodes
, without ever making it longer than 100 items:
for x in randomnodes:
neighbors_list = neighbors(x)
if len(randomnodes) + len(neighbors_list) < 100:
randomnodes.extend(neighbors_list)
else:
randomnodes.extend(neighbors_list[:100-len(randomnodes)]
break
Note that neither your code, nor the code I suggest above makes any effort to ensure there are not duplicate results added to randomnodes
. If your graph may have cycles, you might want to add some logic to avoid that situation. This can't be quite as simple as using a set
for randomnodes
(because you can't modify a set while you're iterating over it), but you can use a set
of seen nodes to filter each neighbor list:
seen = set(randomnodes)
for x in randomnodes:
neighbors_list = [n for n in neighbors(x) if n not in seen]
if len(randomnodes) + len(neighbors_list) < 100:
randomnodes.extend(neighbors_list)
seen.update(neighbors_list)
else:
randomnodes.extend(neighbors_list[:100-len(randomnodes)]
break
Upvotes: 3