【问题标题】:Type Error: unhashable type: 'list' (using dictionary)类型错误:不可散列类型:'list'(使用字典)
【发布时间】:2019-10-05 14:51:41
【问题描述】:

我的代码 unhashable type: 'list' 中出现此错误

我有一个包含此输入的文本文件:

hokejistov hokej
strelena strela
trener trenuje

我想将单词分成 2 行。第一行将包含第一个单词。第二行将包含第二个单词。然后我需要将单词划分为符号。这部分正在工作,但我需要使用字典 (mapka = {'h':1,'o':2,'k':3, 'e':4, 'j':5, 'i':6, 's':7, 't':8,'v':9,'r':10, 'l':11, 'n':12, 'a':13, 'u':14})

在输出我想得到这个:

first = [[1, 2, 3, 4, 5, 6, 7, 8, 2, 9], [7, 8, 10, 4, 11, 4, 12, 13], [8, 10, 4, 12, 4, 10]]
second = [[1, 2, 3, 4, 5], [7, 8, 10, 4, 11, 13], [8, 10, 4, 12, 14, 5, 4]]

这是我的代码

data = [line.strip() for line in open("mamradhokej.txt",'r')]
mapka = {'h':1,'o':2,'k':3, 'e':4, 'j':5, 'i':6, 's':7, 't':8,'v':9, 
        'r':10, 'l':11, 'n':12, 'a':13, 'u':14}

first = [[word.lower() for word in text.split()[0]]for text in data]
second = [[word.lower() for word in text.split()[1]]for text in data]

print(first)
print(second)

map(mapka.get, first)
[mapka[k] for k in first] #here i am getting Type error: unhashable type: 'list'.

【问题讨论】:

  • k 是一个列表,所以这个错误是有意义的
  • 字典键必须是不可变类型以保持字典的健全。如果您需要使用集合作为键,请使用tuple 而不是list。但我不认为这实际上是你想要的。
  • 在这里看看我的回答(listset 中出现同样的错误):stackoverflow.com/a/52805381/1619432
  • first是列表的列表,所以mapka[k]中的k是列表,例如[1, 2, 3, 4, 5, 6, 7, 8, 2, 9],所以mapka[k]不是你想要的,因为没有这个键入mapka

标签: python


【解决方案1】:

为什么会出现这个错误?

字典键必须是可散列的对象。

为了使对象可散列,它应该是实现__eq____hash__ 方法的类的实例。

list 类型的对象不可散列。

您收到此错误的原因是因为first 是一个列表列表。

旁注:hashable 并不意味着在 python 中不可变

解决方案

你需要一个嵌套迭代:

first_output = [[mapka[letter] for letter in word] for word in first] 

second 也是如此。您还可以循环遍历第一个和第二个,以避免代码重复

【讨论】:

    【解决方案2】:

    由于mapka 将应用于字符,因此您应该在字符级别进行迭代。

    在 python 中迭代 字符串,会导致迭代字符。

    所以这应该有效:

    data = ["hokejistov hokej", "strelena strela", "trener trenuje"] 
    second = [[1, 2, 3, 4, 5], [7, 8, 10, 4, 11, 13], [8, 10, 4, 12, 14, 5, 4]]
    mapka = {'h':1,'o':2,'k':3, 'e':4, 'j':5, 'i':6, 's':7, 't':8,'v':9, 
        'r':10, 'l':11, 'n':12, 'a':13, 'u':14}
    
    first = [[word.lower() for word in text.split()[0]]for text in data]
    second = [[word.lower() for word in text.split()[1]]for text in data]
    
    print([[mapka[letter] for letter in word] for word in first])
    print([[mapka[letter] for letter in word] for word in second])
    

    【讨论】:

      【解决方案3】:

      这是一个仅包含列表的解决方案:

      # pretend to read your file
      data = ["hokejistov hokej","strelena strela","trener trenuje"]
      
      # a dictionary is not strictly needed here
      mapka = "hokejistvrlnau"
      
      # convert lines to columns
      columns = []
      for line in data:
          for i,word in enumerate(line.split()):
              try:
                  columns[i].append(word)
              except IndexError:
                  columns.append([word])
      
      print(columns) # [['hokejistov', 'strelena', 'trener'], ['hokej', 'strela', 'trenuje']]
      
      # look up each letter
      for column in columns:
          print( [ [mapka.index(letter)+1  for letter in word] for word in column] )
      
      # [[1, 2, 3, 4, 5, 6, 7, 8, 2, 9], [7, 8, 10, 4, 11, 4, 12, 13], [8, 10, 4, 12, 4, 10]]
      # [[1, 2, 3, 4, 5], [7, 8, 10, 4, 11, 13], [8, 10, 4, 12, 14, 5, 4]]
      

      【讨论】:

        猜你喜欢
        • 2016-01-11
        • 2017-12-27
        • 2012-01-21
        • 2018-08-03
        • 1970-01-01
        • 2019-01-07
        • 1970-01-01
        • 1970-01-01
        • 2021-12-17
        相关资源
        最近更新 更多