Unhashable type: "list" error in python

I have this dictionary:

final = {0: [1, 9], 1: [0, 9], 8: [16, 10], 9: [0, 1], 10: [8, 16], 16: [8, 10]} 

And I wanted to convert it to a list, so I used a list, and the result was as follows:

 myList = [[int(k)]+v for k, v in final.items()] myList = [[0, 1, 9], [0, 1, 9], [0, 1, 9], [8, 10, 16], [8, 10, 16], [8, 10, 16]] 

I also need the whole list, as well as the elements inside each small list that I need to sort, and remove duplicates from the list:

 for i in myList: i.sort() myList.sort() list(set(myList)) print(myList) 

However, when I run this, I get the error " Unhashable type: 'list' " . Is there any other way to implement this? Thanks in advance!

+5
source share
5 answers

List changed; in Python, mutable containers are not hashed. set , in turn, means elements that can be hashed. You can convert lists to tuples, which are immutable containers and thus hashed:

 >>> myList = [[0, 1, 9], [0, 1, 9], [0, 1, 9], [8, 10, 16], [8, 10, 16], [8, 10, 16]] >>> list(set(tuple(i) for i in myList)) [(8, 10, 16), (0, 1, 9)] 

Note that sets are not sorted, so you probably want to sort after creating the set:

 >>> myList = [[0, 1, 9], [0, 1, 9], [0, 1, 9], [8, 10, 16], [8, 10, 16], [8, 10, 16]] >>> sorted(set(tuple(i) for i in myList)) [(0, 1, 9), (8, 10, 16)] 
+3
source

A set needs a list of hashed objects; that is, they are unchanged, and their condition does not change after they are created. The list object has changed since it can change (as shown by the sort function, which constantly reorders the list), which means that it is not hashed, so it does not work with set .

The solution to this is to convert list objects to tuple objects; they will work with set because they are hashed. You can do this by creating a generator, which you then pass in to install:

 >>> list(set(tuple(x) for x in myList)) [(0, 1, 9), (8, 10, 16)] 

Tuples work similar to lists, so this should not cause problems with your existing program. If you really need a list of lists, you can convert it with a list comprehension as follows:

 >>> [list(x) for x in set(tuple(x) for x in myList))] [[0, 1, 9], [8, 10, 16]] 
+1
source

Sure. The change:

 myList = [[int(k)]+v for k, v in final.items()] 

To:

 myList = [tuple([int(k)]+v) for k, v in final.items()] 

This creates a tuple, not a list, for a combination of keys and dictionary values. Tuples are immutable and can be used as values ​​in sets, while lists cannot.

+1
source

myList is a list of lists. When you create a set, the elements of the set must be immutable for the sets to work properly.

In this case, the lists are mutable (you can append or remove elements), this is necessary for the sets to be called, if you could change the contents of the lists, python could not determine if your set of elements repeated or not.

Imagine this case (NOT POSSIBLE, but imagine):

 l1 = [1,2,3] l2 = [1,2] s = set([l1, l2]) #Here both lists are different l2.append(3) #Here both lists are equal 

Python should conclude that you want l1 or l2 to be excluded from the set? Which one of? Why?

One thing you can do is use tuples instead of lists (which are an immutable version of lists) and convert them to settings

0
source

If you are only sorting sublisters to faint, you can use frozensets instead and not sort:

 final = {0: [1, 9], 1: [0, 9], 8: [16, 10], 9: [0, 1], 10: [8, 16], 16: [8, 10]} unique = list(map(list, {frozenset([k] + v) for k, v in final.items()})) 

What will give you:

 [[0, 1, 9], [16, 8, 10]] 

You can still sort the remaining sub-lists, which will still be faster than sorting them first and then deleting them, especially if the sub-lists are large and / or you have a lot of cheats.

 unique = list(map(sorted, {frozenset([k] + v) for k, v in final.items()})) print(unique) 

If necessary, you will receive an ordered output:

 [[0, 1, 9], [8, 10, 16]] 
-1
source

Source: https://habr.com/ru/post/1245583/


All Articles