How To Fix TypeError: unhashable type ‘slice’

Estimated reading time: 2 minutes

So you have a Python dictionary, and you want to retrieve data from it and print it to a screen. There are some characteristics of Python that first of all should be understood:

  1. They are mutable
  2. They also have the ability to grow and shrink as required.
  3. Data is accessed within the dictionary via keys.

The last point is very important as dictionaries do not have an index value, and this is why you get the TypeError you are here to solve for.

So let us recreate the problem

In the below code we have a dictionary called “userdata”, with its key-value pairs.

The loop is trying to retrieve the index value 1 for all the values in dai_data.

As can be seen, dai_data is trying to retrieve the last three index values within the dictionary.

As noted above the only way to access dictionary values is through their key values.

userdata = {
	  "name": "Data Analytics Ireland",
	  "Country": "Ireland",
	  "City": "Dublin",
	  "Age": "1000 years!",
}

dai_data = userdata[:3]

for i in dai_data:
	     print(i[1])

Output:
Traceback (most recent call last):
  File "", line 8, in <module>
    dai_data = userdata[:3]
TypeError: unhashable type: 'slice'

So how do we fix this problem?

First of all, values are accessed through the key within the dictionary

In the below dictionary the key values are: Name, Country, City, Age

userdata = {
	  "Name": "Data Analytics Ireland",
	  "Country": "Ireland",
	  "City": "Dublin",
	  "Age": "1000 years!",
}

print(userdata["Name"])
print(userdata["Country"])
print(userdata["City"])
print(userdata["Age"])

Output:
Data Analytics Ireland
Ireland
Dublin
1000 years!

As a result, now we are able to access the values associated with each key.

Did you know you could add a list to one of your key-value pairs?

In the above example, we focused on a single value, but we could also make a key equal to a list.

userdata = {
	  "Name": ["Joe","Jim"],
	  "Country": "Ireland",
	  "City": ["Dublin","Cork","Limerick"],
	  "Age": "1000 years!"
}

print(userdata["Name"])
print(userdata["Country"])
print(userdata["City"])
print(userdata["Age"])

Output:
['Joe', 'Jim']
Ireland
['Dublin', 'Cork', 'Limerick']
1000 years!

TypeError: List Indices Must Be Integers Or Slices, Not Tuple

Estimated reading time: 3 minutes

When working with Python lists in your data analytics projects, when you trying to read the data, a common problem occurs if you have a list of lists, and it is not properly formatted.

In this instance, Python will not be able to read one or more lists and as a result, will throw this error.

In order to understand how this problem occurs, we need to understand how to create a list of lists.

How to create a lists of lists

Let’s look at a simple list:

a = [1,2,3]
print(a)
print(type(a))

Result:
[1, 2, 3]
<class 'list'>

Let’s create a second list called b:

b = [4,5,6]
print(b)
print(type(b))

Result:
[4, 5, 6]
<class 'list'>

So if we want to join the lists together into one list ( hence a list of lists) then:

a = [1,2,3]
b = [4,5,6]

list_of_lists = []
list_of_lists.append(a)
list_of_lists.append(b)
print(list_of_lists)
print(type(list_of_lists))

Result:
[[1, 2, 3], [4, 5, 6]]
<class 'list'>

So as can be seen the two lists are contained within a master list called “list_of_lists”.

So why does the error list indices must be integers or slices, not tuple occur?

Reason 1 ( Missing commas between lists)

If you manually type them in and forget the comma between the lists this will cause your problem:

a=[[1,2,3][4,5,6]]
print(a)

Result (Error):
Traceback (most recent call last):
  line 10, in <module>
    a=[[1,2,3][4,5,6]]
TypeError: list indices must be integers or slices, not tuple

But if you put a comma between the two lists then it returns no error:

a=[[1,2,3],[4,5,6]]
print(a)

Result (no error):
[[1, 2, 3], [4, 5, 6]]
Process finished with exit code 0

Reason 2 ( Comma in the wrong place)

Sometimes you have a list, and you only want to bring back some elements of the list, but not others:

In the below, we are trying to bring back the first two elements of the list.

a= [1,2,3,4,5]
print(a[0:,2])

Result:
Traceback (most recent call last):
   line 14, in <module>
    print(a[0:,2])
TypeError: list indices must be integers or slices, not tuple

The reason that the same error happens is the additional comma in a[0:,2], causes the error to appear as Python does not know how to process it.

This is easily fixed by removing the additional comma as follows:

a= [1,2,3,4,5]
print(a[0:2])

Result:
[1, 2]
Process finished with exit code 0

So why is there a mention of tuples in the error output?

The final piece of the jigsaw needs to understand why there is a reference to a tuple in the error output?

If we return to a looking at a list of lists and look at their index values:

a=[[1,2,3],[4,5,6]]
z = [index for index, value in enumerate(a)]
print(z)

Result:
[0, 1]
Process finished with exit code 0

As can be seen, the index values are 0,1, which is correct.

As before removing the comma gives the error we are trying to solve for:

a=[[1,2,3][4,5,6]]
z = [index for index, value in enumerate(a)]
print(z)

Result:
Traceback (most recent call last):
  line 16, in <module>
    a=[[1,2,3][4,5,6]]
TypeError: list indices must be integers or slices, not tuple

BUT the reference to the tuple comes from the fact that when you pass two arguments (say an index value) a Tuple is created, but in this instance, as the comma is missing the tuple is not created and the error is called.

This stems from the __getitem__ for a list built-in class cannot deal with tuple arguments that are not integers ( i.e. 0,1 like we have returned here) , so the error is thrown, it is looking for the two index values to pass into a tuple.

IndexError: list index out of range

Estimated reading time: 3 minutes

Are you working with lists and getting the error IndexError: list index out of range while using Python? There is a very simple explanation to this, and its fix is very easy.

First of all lets understand what is going on with the list.

Traceback (most recent call last):
  File "C:/Users/haugh/OneDrive/dataanalyticsireland/YOUTUBE/IndexError_list_index_out_of_range/INDEX_ERROR_LIST_INDEX_OUT_OF_RANGE.py", line 4, in <module>
    print(data[4])
IndexError: list index out of range

Lists and their index values

In the below list, we have outputted its values and index values.

data = ['a','b','c','d']
for (i,item) in enumerate(data, start=0): #===> Loops through list and applies index values starting at zero
    print(i,item)

Output:
0 a
1 b
2 c
3 d

Process finished with exit code 0

As can be seen the program returns the list values and their indexes. Note that the index starts at zero as we have set start=0.

Start=0 can be set to any value you like, as can be seen here:

data = ['a','b','c','d']
for (i,item) in enumerate(data, start=1): #===> Loops through list and applies index values starting at zero
    print(i,item)

Output:
1 a
2 b
3 c
4 d

Process finished with exit code 0

OR

data = ['a','b','c','d']
for (i,item) in enumerate(data, start=22): #===> Loops through list and applies index values starting at zero
    print(i,item)

Output:
22 a
23 b
24 c
25 d

Process finished with exit code 0

The purpose of the index value is to tell the program where to start its index from, if left empty it starts at zero.

Lists and the no of index values

In the above examples the index values all occur on four rows.

This is important as when you are looping through the rows, it will not go beyond the length of the rows.

So in this example the enumerate function specifically counts the no rows and stores the index values with each, and then loops through the list till it hits the last one, without error.

data = ['a','b','c','d']
for (i,item) in enumerate(data, start=0): #===> Loops through list and applies index values starting at zero
    print(i,item)

Output:
0 a
1 b
2 c
3 d

Process finished with exit code 0

How to fix the error IndexError: list index out of range

So the reason we get the below is that the line print(data[4]) is looking for the row with index value 4, but we know that from observation that does not exist.

To fix this we would change the value 4 in print(data[4]) to any of 0,1,2,3, as they are the index values associated with the list.

data = ['a','b','c','d']
for (i,item) in enumerate(data, start=0): #===> Loops through list and applies index values starting at zero
    print(i,item)
print(data[4])

Output:
Traceback (most recent call last):
  File "C:/Users/haugh/OneDrive/dataanalyticsireland/YOUTUBE/IndexError_list_index_out_of_range/INDEX_ERROR_LIST_INDEX_OUT_OF_RANGE.py", line 4, in <module>
    print(data[4])
IndexError: list index out of range
0 a
1 b
2 c
3 d

Applying a correct valid index value:
data = ['a','b','c','d']
for (i,item) in enumerate(data, start=0): #===> Loops through list and applies index values starting at zero
    print(i,item)
print(data[3])

Yields with no error:
0 a
1 b
2 c
3 d
d

So in summary when working with lists and their index values it is important:

(A) Understand the length of your list.

(B) Where your index values start and finish.

This error is easily fixable, but in your code you just need to make sure that you referencing values that are in the range of your index values.