Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tut] How to Fix TypeError: unhashable type: ‘list’
1
How to Fix TypeError: unhashable type: ‘list’

5/5 – (2 votes)

The
Code:
TypeError: unhashable type: 'list'
usually occurs when you try to use a list object as a set element or dictionary key and Python internally passes the unhashable list into the
Code:
hash()
function. But as lists are mutable objects, they do not have a fixed hash value. The easiest way to fix this error is to use a hashable tuple instead of a non-hashable list as a dictionary key or set element.

We’ll show how this is done in the remaining article. The last method is a unique way to still use lists in sets or dictionary keys that you likely won’t find anywhere else, so keep reading and learn something new! [Image: 1f41d.png]

Problem Formulation and Explanation

[Image: 1f4ac.png] Question: How to fix the
Code:
TypeError: unhashable type: 'list'
in your Python script?

There are two common reasons for this error:
  • You try to use a list as a dictionary key, or

  • You try to use a list as a set element.

This is not a trivial problem because Python lists are mutable and, therefore, not hashable.

Here’s the first example:

Code:
my_list = [1, 2, 3] my_dict = {} my_dict[my_list] = 'hello Finxters!' ''' Traceback (most recent call last): File "C:\Users\xcent\Desktop\code.py", line 3, in <module> my_dict[my_list] = 'hello Finxters!' TypeError: unhashable type: 'list' '''

And here’s the second example:

Code:
my_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] my_set = set(my_list) ''' Traceback (most recent call last): File "C:\Users\xcent\Desktop\code.py", line 2, in <module> my_set = set(my_list) TypeError: unhashable type: 'list' '''

As you’ve seen in the previous two code snippets, the
Code:
TypeError: unhashable type: 'list'
usually occurs when you try to use a list object as a set element or dictionary key.

But let’s dive deeper to find the real reason for the error:

[Image: 1fab2.png] Minimal Reproducible Error Example: Lists are mutable objects so they do not have a fixed hash value. In fact, the error can be reproduced most easily when calling
Code:
hash(lst)
on a list object
Code:
lst
.

This is shown in the following minimal example that causes the error:

Code:
hash([1, 2, 3])

The output is the error message:

Code:
Traceback (most recent call last): File "C:\Users\xcent\Desktop\code.py", line 1, in <module> hash([1, 2, 3]) TypeError: unhashable type: 'list'

Because you cannot successfully pass a list into the
Code:
hash()
function, you cannot directly use lists as set elements or dictionary keys.

But let’s dive into some solutions to this problem!

Method 1: Use Tuple Instead of List as Dictionary Key

The easiest way to fix the
Code:
TypeError: unhashable type: 'list'
is to use a hashable tuple instead of a non-hashable list as a dictionary key. For example, whereas
Code:
d[my_list]
will raise the error, you can simply use
Code:
d[tuple(my_list)]
to fix the error.

Here’s an example of what you can do instead:

Code:
my_list = [1, 2, 3] my_dict = {} my_dict[tuple(my_list)] = 'hello Finxters!' print(my_dict) # {(1, 2, 3): 'hello Finxters!'}

The error may also occur when you try to use a list as a set element. Next, you’ll learn what to do in that case:

Method 2: Use Tuple Instead of List as Set Element

To fix the
Code:
TypeError: unhashable type: 'list'
when trying to use a list as a set element is to use a hashable tuple instead of a non-hashable list. For example, whereas
Code:
set.add([1, 2])
will raise the error, you can simply use
Code:
set.add((1, 2))
or
Code:
set.add(tuple([1, 2]))
to fix the error.

Here’s a minimal example:

Code:
my_set = set() # Error: my_set.add([1, 2]) # This is how to resolve the error: my_set.add((1, 2)) # Or: my_set.add(tuple([1, 2])) print(my_set) # {(1, 2)}

If you want to convert a list of lists to a set, you can check out my detailed tutorial on the Finxter blog:

[Image: 1f30e.png] Related Tutorial: How to convert a list of lists to a set?

Method 3: Use String Representation of List as Set Element or Dict Key

To fix the
Code:
TypeError: unhashable type: 'list'
, you can also use a string representation of the list obtained with
Code:
str(my_list)
as a set element or dictionary key. Strings are hashable and immutable, so Python won’t raise the error when using this approach.

Here’s an example:

Code:
my_list = [1, 2, 3] # 1. Use str repr of list as dict key: d = {} d[str(my_list)] = 'hello Finxters' # 2. Use str repr of list as set element: s = set() s.add(str(my_list))

In both cases, we used the string representation of the list instead of the list itself. The string is immutable and hashable and it fixes the error.

But what if you really need a mutable set or dictionary key? Well, you shouldn’t but you can by using this approach:

Method 4: Create Hashable Wrapper List Class

You can still use a mutable list as a dictionary key, set element, or argument of the
Code:
hash()
function by defining a wrapper class, say HackedList, that overrides the
Code:
__hash__()
dunder method.

Python’s built-in
Code:
hash(object)
function takes one object as an argument and returns its hash value as an integer. You can view this hash value as a unique fingerprint of this object.

The Python
Code:
__hash__()
method implements the built-in
Code:
hash()
function.

Here’s the minimal code example that creates a wrapper class HackedList that overrides the
Code:
__hash__()
dunder method so you can use an instance of
Code:
HackedList
as a dictionary key, set element, or just as input to the
Code:
hash()
function:

Code:
my_list = [1, 2, 3] class HackedList: def __init__(self, lst): self.lst = lst def __hash__(self): return len(self.lst) my_hacked_list = HackedList(my_list) # 1. Pass hacked list into hash() function: print(hash(my_hacked_list)) # Output: 3 # 2. Use hacked list as dictionary key: d = dict() d[my_hacked_list] = 'hello Finxters' # 3: Use hacked list as set element: s = set() s.add(my_hacked_list)

Here’s the content of the dictionary and set defined previously:

Code:
{<__main__.HackedList object at 0x0000016CFB0BDFA0>: 'hello Finxters'} {<__main__.HackedList object at 0x0000016CFB0BDFA0>}

If you want to fix the ugly output, you can additionally define the
Code:
__str__()
and
Code:
__repr__()
magic methods like so:

Code:
my_list = [1, 2, 3] class HackedList: def __init__(self, lst): self.lst = lst def __hash__(self): return len(self.lst) def __str__(self): return str(self.lst) def __repr__(self): return str(self.lst) my_hacked_list = HackedList(my_list) # 1. Pass hacked list into hash() function: print(hash(my_hacked_list)) # Output: 3 # 2. Use hacked list as dictionary key: d = dict() d[my_hacked_list] = 'hello Finxters' # 3: Use hacked list as set element: s = set() s.add(my_hacked_list) print(d) print(s)

Beautiful output:

Code:
{[1, 2, 3]: 'hello Finxters'} {[1, 2, 3]}
Summary

The five most Pythonic ways to convert a list of lists to a set in Python are:

Feel free to check out more free tutorials and cheat sheets for learning and improving your Python skills in our free email academy:

Nerd Humor

[Image: image-72.png][i]Oh yeah, I didn’t even know they renamed it the Willis Tower in 2009, because I know a normal amount about skyscrapers. — xkcd (source)[/i]
Reply

Users browsing this thread:
1 Guest(s)


Forum Jump: