Python。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'`。我知道字典中的键不能是列表,但我想把我的值变成一个列表而不是键。我想知道我是否在某处犯了错误。
解决办法

正如其他答案所指出的,这个错误是由于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')作为f:(甚至with open('filename.txt', 'r')作为f:)打开文件,它应该能正常工作。

评论(3)

你试图用k(是一个列表)作为d的键。列表是可变的,不能作为dict的键。

而且,由于这一行,你从未初始化 dictionary 中的 list。

if k not in d == False:

这应该是。

if k not in d == True:

这实际上应该是。

if k not in d:
评论(1)

发生 "类型错误 "是因为 "k "是一个列表,因为它是用另一个列表的切片创建的,行文是k = list[0:j]。 这可能应该是k = ' '.join(list[0:j]),所以你有一个字符串代替。

除此之外,你的if'语句不正确,正如Jesse'的答案所指出的,应该是if k不在d中if not k在d中`(我喜欢后者)。

由于你在 "for "循环中使用了 "d = {}",所以你也在每次迭代中清除了你的字典。

请注意,你也不应该使用list'或file'作为变量名,因为你要屏蔽内建程序。

以下是我对你的代码的改写方式。

d = {}
with open("filename.txt", "r") as input_file:
    for line in input_file:
        fields = line.split()
        j = fields.index("x")
        k = " ".join(fields[:j])
        d.setdefault(k, []).append(" ".join(fields[j+1:]))

上面的dict.setdefault()方法取代了你代码中的if k不在d中逻辑。

评论(3)