TypeError:unhashable类型:python中的'list'

时间:2015-06-05 04:39:18

标签: python networkx

我是python的新手,我正在尝试执行以下操作:

  1. 从列表x中依次获取元素randomnodes,并将neighbors of x附加到列表的末尾。
  2. 重复此操作,直到列表大小为100。
  3. 我写的代码如下:

    for x in randomnodes:
        if len(randomnodes)<=100:
            randomnodes.append(neighbors(x))
    

    其中neighbors(x)返回一个列表。

    但是代码出错了:

    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'
    

    为什么会这样?如何修改代码以实现任务?

1 个答案:

答案 0 :(得分:3)

您遇到的麻烦是您将邻居列表添加到randomnodes的末尾,而不是从列表中添加元素。这导致稍后的迭代尝试获取嵌套邻居列表的邻居,从而导致异常。

如果您不介意randomnodes列表有时会获得一些额外的元素,则可以在当前代码中将append替换为extend

否则,请尝试使用list.extend稍微复杂的代码,将邻居列表中的相应数字元素添加到randomnodes,而不要超过100个项目:

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

请注意,您的代码和我上面建议的代码都不会努力确保没有向randomnodes添加重复结果。如果您的图表可能有周期,您可能需要添加一些逻辑来避免这种情况。这可能就像对set使用randomnodes一样简单(因为你可以在迭代时修改集合),但是你可以使用一个set个看到过的节点来过滤每个邻居列表:

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