I have two lists and I need to rank their elements with the Borda positional ranking. so I made this function, but I have this error:
TypeError: unhashable type: 'list'.
As indicated by other answers The problem is that I can't use a list as the key in a dict, since dict keys need to be immutable.So I used a tuple instead, but the error remains.
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')])]
I open the two files as list in this way
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)
Can someone help?
Note that the restriction with keys in Python dictionary is only immutable data types can be used as keys, which means we cannot use a dictionary of list as a key .
You can convert a Python list to a dictionary using the dict. fromkeys() method, a dictionary comprehension, or the zip() method. The zip() method is useful if you want to merge two lists into a dictionary.
A tuple containing a list cannot be used as a key in a dictionary. Answer: True. A list is mutable. Therefore, a tuple containing a list cannot be used as a key in a dictionary.
In computer science, a hash list is typically a list of hashes of the data blocks in a file or set of files. Lists of hashes are used for many different purposes, such as fast table lookup (hash tables) and distributed databases (distributed hash tables).
Since your lists have complex elements (tuple of list of tuples of strings), they have to be converted to contain tuples of tuples of strings so they are hashable. Like this:
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 ANSWER If you have list1 and list2, the way to call this function is borda_sort([list1, list2])
(or borda_sort((list1, list2))
, either works the same). If your lists contain individual elements in the same order that you want to use for borda, the answer is to make a list of lists, not to zip your lists together. I think zip()
doesn't do what you think it does. zip makes a list of pairs from a pair of lists, like this:
>>> zip((1, 2, 3), ('a', 'b', 'c'))
[(1, 'a'), (2, 'b'), (3, 'c')]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With