[英]Use a list as the key in a Python dict
我有兩個列表,我需要將他們的元素與Borda排名進行排名。 所以我做了這個功能,但是我有這個錯誤:
TypeError: unhashable type: 'list'.
正如其他答案所示問題是我不能使用列表作為dict中的鍵,因為dict鍵需要是不可變的。所以我使用了一個元組,但錯誤仍然存在。
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)
有人可以幫忙嗎?
使用元組而不是列表。 它們可以用作詞典中的鍵。 假設列表具有固定數量的元素。 即len(列表)對於所有列表和常量是相同的。
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.
由於您的列表具有復雜元素(字符串元組列表的元組),因此必須將它們轉換為包含字符串元組的元組,以便它們可以清除。 像這樣:
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')]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.