【问题标题】:Use a list as the key in a Python dict使用列表作为 Python 字典中的键
【发布时间】:2023-03-27 18:23:01
【问题描述】:

我有两个列表,我需要使用 Borda 位置排名对它们的元素进行排名。所以我做了这个功能,但我有这个错误:

TypeError: unhashable type: 'list'. 

正如其他答案所示问题是我不能使用列表作为字典中的键,因为字典键需要是不可变的。所以我改用元组,但错误仍然存​​在。

The files of the two lists look like this
list1 = [([('diritti', 'S'), ('umani', 'A')]), ([('violazioni', 'S'), ('dei', 'E'), ('diritti', 'S'), ('umani', 'A')]), ([('forze', 'S'), ('di', 'E'), ('sicurezza', 'S')]), ([('violazioni', 'S'), ('dei', 'E'), ('diritti', 'S')]), ([('Nazioni', 'SP'), ('Unite', 'SP')]), ([('anni', 'S'), ('di', 'E'), ('carcere', 'S')])] 
list2 = [([('anni', 'S'), ('di', 'E'), ('carcere', 'S')]), ([('diritti', 'S'), ('umani', 'A')]), ([('forze', 'S'), ('di', 'E'), ('sicurezza', 'S')]), ([('violazioni', 'S'), ('dei', 'E'), ('diritti', 'S'), ('umani', 'A')]), ([('violazioni', 'S'), ('dei', 'E'), ('diritti', 'S')]), ([('Nazioni', 'SP'), ('Unite', 'SP')]), ([('uso', 'S'), ('eccessivo', 'A'), ('della', 'E'), ('forza', 'S')])] 

我这样打开两个文件作为列表

list1 = codecs.open('/home/list1', 'r', 'utf-8').read()
list2 = codecs.open('/home/list2', 'r', 'utf-8').read()
li = ast.literal_eval(list1)
lii = ast.literal_eval(list2)

def borda_sort(lists):
###Borda’s positional ranking combines ranked lists using information of the ordinal ranks of the elements in each list.Given lists t1, t2, t3 ... tk, for each candidate c and list ti, the score B ti (c) is the number of candidates ranked below c in ti. So The total Borda score is B(c) = ∑ B ti (c) The candidates are then sorted by descending Borda scores. Given the lists = [ ['a', 'c'], ['b', 'd', 'a'], ['b', 'a', 'c', 'd'] ], the output will be ['b', 'a', 'c', 'd']
    scores = {}
    for l in lists:
        for idx, elem in enumerate(reversed(l)):
            if not elem in scores:
                scores[elem] = 0
            scores[elem] += idx
    return sorted(scores.keys(), key=lambda elem: scores[elem], reverse=True)

lists = zip(li, lii)
print borda_sort(lists)

有人可以帮忙吗?

【问题讨论】:

  • 列表不能用作 dict 的键。也许将列表转换为字符串可以解决您的问题?
  • this 的副本。
  • 也许用字典来反映你的列表?
  • 你说你使用了一个元组,但我在任何地方都没有看到。你能告诉我们错误来自哪一行吗?
  • 不相关:您可以使用 json 来存储列表而不是 Python 文字 (ast.literal_eval())。

标签: python list python-2.7


【解决方案1】:

由于您的列表具有复杂的元素(字符串元组列表的元组),因此必须将它们转换为包含字符串元组的元组,以便它们是可散列的。像这样:

list1a = [ tuple(x) for x in list1 ]
list2a = [ tuple(x) for x in list2 ]

print borda_sort([list1a, list2a])

# prints [(('diritti', 'S'), ('umani', 'A')), (('forze', 'S'), ('di', 'E'), ('sicurezza', 'S')), (('violazioni', 'S'), ('dei', 'E'), ('diritti', 'S'), ('umani', 'A')), (('anni', 'S'), ('di', 'E'), ('carcere', 'S')), (('violazioni', 'S'), ('dei', 'E'), ('diritti', 'S')), (('Nazioni', 'SP'), ('Unite', 'SP')), (('uso', 'S'), ('eccessivo', 'A'), ('della', 'E'), ('forza', 'S'))]

老答案如果你有list1和list2,调用这个函数的方法是borda_sort([list1, list2])(或者borda_sort((list1, list2)),两者都一样)。如果您的列表包含的单个元素的顺序与您希望用于 borda 的顺序相同,则答案是制作一个列表列表,而不是将您的列表压缩在一起。我认为zip() 没有做你认为的事情。 zip 从一对列表中创建一个对列表,如下所示:

>>> zip((1, 2, 3), ('a', 'b', 'c'))
[(1, 'a'), (2, 'b'), (3, 'c')]

【讨论】:

    【解决方案2】:

    使用元组而不是列表。它们可以用作字典中的键。假设列表具有固定数量的元素。 IE。 len(list) 对于所有列表和常量都是相同的。

    scores = {}
    for l in lists:
        for idx, elem in enumerate(reversed(l)):
            if not elem in scores:
                scores[tuple(elem)] = 0    #Notice that i have converted list to a tuple.
            scores[tuple(elem)] += idx     #Notice that i have converted list to a tuple.
    return sorted(scores.keys(), key=lambda elem: scores[tuple(elem)], reverse=True) #Notice that i have converted list to a tuple.
    

    【讨论】:

    • 回溯(最近一次调用最后):文件“/home/”,第 48 行,在 中 print borda_sort(lists) 文件“/home/fat.py”,第 42 行,在 borda_sort如果分数中没有元素:TypeError: unhashable type: 'list'
    • 忘记将一个列表更改为元组。我将更新上面的代码。但是重点是您必须更改所有应该是元组键的列表。
    • 错误依旧:TypeError: unhashable type: 'list'
    猜你喜欢
    • 2020-08-04
    • 2014-10-10
    • 1970-01-01
    • 1970-01-01
    • 2013-01-26
    • 2022-11-12
    • 2020-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多