简体   繁体   中英

TypeError: unhashable type: 'list' in python

I am new to python and I am trying to do the following:

  1. Take an element x sequentially from a list randomnodes and append the neighbors of x at the end of the list.
  2. Repeat this until the size of the list is 100.

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?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM