如何克服 TypeError: unhashable type: 'list'

新手上路,请多包涵

我正在尝试获取一个如下所示的文件:

 AAA x 111
AAB x 111
AAA x 112
AAC x 123
...

并使用字典使输出看起来像这样

{AAA: ['111', '112'], AAB: ['111'], AAC: [123], ...}

这是我试过的

file = open("filename.txt", "r")
readline = file.readline().rstrip()
while readline!= "":
    list = []
    list = readline.split(" ")
    j = list.index("x")
    k = list[0:j]
    v = list[j + 1:]
    d = {}
    if k not in d == False:
        d[k] = []
    d[k].append(v)
    readline = file.readline().rstrip()

我不断收到 TypeError: unhashable type: 'list' 。我知道字典中的键不能是列表,但我试图将我的值变成列表而不是键。我想知道我是否在某处犯了错误。

原文由 Keenan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

如其他答案所示,错误是由于 k = list[0:j] 造成的,您的密钥已转换为列表。您可以尝试的一件事是重新编写代码以利用 split 函数:

 # Using with ensures that the file is properly closed when you're done
with open('filename.txt', 'rb') as f:
  d = {}
  # Here we use readlines() to split the file into a list where each element is a line
  for line in f.readlines():
    # Now we split the file on `x`, since the part before the x will be
    # the key and the part after the value
    line = line.split('x')
    # Take the line parts and strip out the spaces, assigning them to the variables
    # Once you get a bit more comfortable, this works as well:
    # key, value = [x.strip() for x in line]
    key = line[0].strip()
    value = line[1].strip()
    # Now we check if the dictionary contains the key; if so, append the new value,
    # and if not, make a new list that contains the current value
    # (For future reference, this is a great place for a defaultdict :)
    if key in d:
      d[key].append(value)
    else:
      d[key] = [value]

print d
# {'AAA': ['111', '112'], 'AAC': ['123'], 'AAB': ['111']}

请注意,如果您使用的是 Python 3.x,则必须稍作调整才能使其正常工作。如果您使用 rb 打开文件,则需要使用 line = line.split(b'x') (确保您使用正确类型的字符串拆分字节)。您也可以使用 with open('filename.txt', 'rU') as f: (甚至 with open('filename.txt', 'r') as f: )打开文件,它应该可以正常工作。

原文由 RocketDonkey 发布,翻译遵循 CC BY-SA 3.0 许可协议

注意: 此答案并未明确回答提出的问题。其他答案可以做到。由于问题特定 于场景 并且引发的 异常是一般 的,因此该答案指向一般情况。

哈希值只是整数,用于在字典查找期间快速比较字典键。

在内部, hash() 方法调用 __hash__() 默认为任何对象设置的对象方法。

嵌套列表转换为集合

>>> a = [1,2,3,4,[5,6,7],8,9]
>>> set(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

发生这种情况是因为列表中的列表是无法散列的列表。这可以通过 将内部嵌套列表转换为元组 来解决,

 >>> set([1, 2, 3, 4, (5, 6, 7), 8, 9])
set([1, 2, 3, 4, 8, 9, (5, 6, 7)])

显式散列 嵌套列表

>>> hash([1, 2, 3, [4, 5,], 6, 7])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

>>> hash(tuple([1, 2, 3, [4, 5,], 6, 7]))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

>>> hash(tuple([1, 2, 3, tuple([4, 5,]), 6, 7]))
-7943504827826258506

避免此错误的解决方案是重组列表以使用嵌套元组而不是列表。

原文由 All Іѕ Vаиітy 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题