2015-05-16 4 views
0

У меня есть два списка, и мне нужно ранжировать их элементы с позиционным рангом Borda. поэтому я сделал эту функцию, но у меня есть эта ошибка:Используйте список как ключ в питоне Python

TypeError: unhashable type: 'list'. 

Как указано в других ответах Проблема заключается в том, что я не могу использовать список в качестве ключа в Словаре, так как ключи 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) 

Может кто-то помочь?

+0

Списки не могут использоваться в качестве ключей для dict. Может быть, листинг списков строк будет решить вашу проблему? –

+0

Дубликат [this] (http://stackoverflow.com/questions/7257588/why-cant-i-use-a-list-as-a-dict-key-in-python). –

+0

Может быть, зеркало вашего списка с помощью dict? – razzmataz

ответ

1

Поскольку ваши списки имеют сложные элементы (кортеж из списка кортежей строк), они должны быть преобразованы, чтобы содержать кортежи кортежей строк, чтобы они hashable. Как это:

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'))] 

OLD ОТВЕТ Если у вас есть 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')] 
+0

@ user3573552: Спасибо, ответ обновлен. –

1

Используйте кортеж вместо списков. Они могут использоваться как ключи в словарях. Предполагая, что списки имеют фиксированное количество элементов. То есть 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. 
+0

Traceback (самый последний вызов последнего): Файл "/ дома /", строка 48, в печати borda_sort (списки) Файл "/home/fat.py", строка 42, в borda_sort если не Элем в баллах : ТипError: unhashable type: 'list' – sss

+0

Забыл изменить один список на кортеж. Я обновлю код выше. Однако главное, что вы должны изменить все списки, которые должны быть ключами к кортежам. – NegativeFeedbackLoop

+0

ошибка остается: TypeError: unhashable type: 'list' – sss

Смежные вопросы