How to fix TypeError: unhashable type: 'slice'

When working with Python dictionaries and pandas DataFrames, you might get the following error:

TypeError: unhashable type: 'slice'

This error occurs when you try to access a dictionary object using a slice. There are two possible reasons why this error happens:

  1. You try to slice a dictionary object
  2. You try to encode categorical data stored in a DataFrame

The following tutorial shows how to fix this error in both scenarios.

1. Slicing a dictionary object

Suppose you have a dictionary object as follows:

product = {
    "name": "iPhone 14",
    "brand": "Apple",
    "price": 999,
    "storage": "256GB",
    "color": "Blue"
}

Next, you want to create a slice of this dictionary by assigning the first two key-value pairs to a new variable:

product_slice = product[:2]

But because a dictionary can’t be sliced like a list, you get this error:

Traceback (most recent call last):
  File "main.py", line 9, in <module>
    product_slice = product[:2]
TypeError: unhashable type: 'slice'

The error happens because you can’t slice a dictionary, but it’s also confusing because Python assumes the slice is the key value.

This ambiguity occurs because the syntax to add a new key-value pair to a dictionary is the same as accessing one. If you switch the assignment a bit, it starts to make sense:

product[:2] = 'Name'

# TypeError: unhashable type: 'slice'

If you’re adding a new key-value pair to a dictionary, then the error makes sense because you can’t specify a slice as the key in a dictionary object. You can only use hashable types like str or int.

But when you try to slice a dictionary, the error message is not so intuitive, so it doesn’t help you to understand what’s wrong. A better error message might be “Can’t slice a dictionary object.”

To resolve this error, you need to access a dictionary values using the keys like this:

product = {
    "name": "iPhone 14",
    "brand": "Apple",
    "price": 999,
    "storage": "256GB",
    "color": "Blue"
}

product_slice = {
    "name": product["name"],
    "brand": product["brand"]
}

You can’t use a slicing syntax to get some of key-value pairs from a dictionary because that’s not how a dictionary is designed.

You can only slice sequences like a string, a list, or a tuple in Python.

2. Encoding categorical data in pandas DataFrame

If you’re working with a pandas DataFrame object, this error can occur when you try to encode categorical data using scikit-learn’s LabelEncoder.

The following DataFrame has one categorical data column named country:

df = pd.DataFrame({
        "country": ["France", "Spain", "France", "Germany"],
        "age": [29, 26, 28, 22],
        "salary": [72000, 83000, 67000, 77000],
        "purchased": ["yes", "no", "yes", "no"],
    })

You want to encode the country column, so you use the slicing syntax with the DataFrame object:

from sklearn.preprocessing import LabelEncoder

labelencoder_X = LabelEncoder()
df[:, 0] = labelencoder_X.fit_transform(df.iloc[:, 0])

The highlighted line above causes the error:

Traceback (most recent call last):
  File "main.py", line 15, in <module>
    df[:, 0] = labelencoder_X.fit_transform(df.iloc[:, 0])
TypeError: unhashable type: 'slice'

The error is not because of the fit_transform method, but because you can’t use slicing syntax to assign new values to a DataFrame object.

The right approach is to use the iloc() method or the column name as shown below:

df.iloc[:, 0] = labelencoder_X.fit_transform(df.iloc[:, 0])

# or
df['country'] = labelencoder_X.fit_transform(df['country'])

Just like with dictionaries, you can’t assign new values to a DataFrame column using the slicing syntax.

You need to use the iloc() method or pass the column name directly inside the square brackets.

Now you’ve learned how to fix the error unhashable type: 'slice'. Until next time! 👋

Take your skills to the next level ⚡️

I'm sending out an occasional email with the latest tutorials on programming, web development, and statistics. Drop your email in the box below and I'll send new stuff straight into your inbox!

No spam. Unsubscribe anytime.