Skip to content

How to Resolve "TypeError: unhashable type: 'slice'" in Python

Fix the Python error when trying to slice dictionaries or DataFrames incorrectly, with solutions for dictionary items and proper Pandas .iloc/.loc usage.

The TypeError: unhashable type: 'slice' error in Python occurs when you try to use slice notation ([:]) directly on an object that doesn't support it. This most commonly happens when attempting to slice a dictionary directly or when using incorrect syntax with Pandas DataFrames.

This guide explains the causes and provides correct solutions for both scenarios.

Dictionaries and Slicing: Why It Doesn't Work

Standard Python dictionaries (dict) are not sequences. They are mappings from keys to values. Slicing, which extracts a subsequence, only works on ordered sequences like lists, tuples, and strings.

a_dict = {
    'id': 1,
    'name': 'Tom Nolan',
    'age': 30,
}
  • The attempt to slice a_dict using [:2] directly causes the TypeError.

Slicing Dictionary Items (Keys, Values, or Key-Value Pairs)

If you need to "slice" a dictionary (get a subset of items based on insertion order), you must first convert the relevant part of the dictionary (keys, values, or items) into a list. Then, you can slice the list.

a_dict = {
    'id': 1,
    'name': 'Tom Nolan',
    'age': 30,
}

keys_slice = list(a_dict.keys())[:2]        # Convert keys to a list, then slice
print(keys_slice)                           # Output: ['id', 'name']

values_slice = list(a_dict.values())[:2]    # Convert values to a list, then slice
print(values_slice)                         # Output: [1, 'Tom Nolan']

items_slice = list(a_dict.items())[:2]      # Convert items to a list of tuples, then slice
print(items_slice)                          # Output: [('id', 1), ('name', 'Tom Nolan')]

sliced_dict = dict(list(a_dict.items())[:2])
print(sliced_dict)                           # Output: {'id': 1, 'name': 'Tom Nolan'}
  • The example shows how to get a slice of the dictionary's keys, values or key-value pairs.
  • The view objects returned by .keys(), .values(), and .items() are not directly sliceable. You must convert them to lists first using list().
  • To create a new dictionary from the sliced items, use dict() on the sliced list of tuples.

Pandas DataFrames and Slicing: iloc and loc

Pandas DataFrames are not dictionaries, though they have some similarities. You can not slice a DataFrame directly using df[start:stop]. Instead, you must use the .iloc (integer-location based) or .loc (label-based) indexers.

Using .iloc (Integer-Based Indexing)

.iloc uses integer positions to select rows and columns, similar to list slicing:

import pandas as pd

data = {
    'id': [1, 2, 3, 4],
    'name': ['Alice', 'Bob', 'Carl', 'Dan'],
    'salary': [100, 50, 75, 150],
    'experience': [5, 7, 9, 13],
    'task': ['dev', 'test', 'ship', 'manage'],
}

df = pd.DataFrame(data)

print(df.iloc[1:3, :])

Output:

   id  name  salary  experience  task
1   2   Bob      50           7  test
2   3  Carl      75           9  ship
  • df.iloc[1:3, :]: Selects rows with indices 1 and 2, and all columns (:). The first indexer is for rows, the second is for columns.

Using .loc (Label-Based Indexing)

.loc uses labels (row labels, which are often integers but can be strings, and column names):

import pandas as pd
data = {
    'id': [1, 2, 3, 4],
    'name': ['Alice', 'Bob', 'Carl', 'Dan'],
    'salary': [100, 50, 75, 150],
    'experience': [5, 7, 9, 13],
    'task': ['dev', 'test', 'ship', 'manage'],
}
df = pd.DataFrame(data)
print(df.loc[1:3, ['name', 'salary']])

Output:

   name  salary
1   Bob      50
2  Carl      75
3   Dan     150
  • This code uses label based indexing to select the specified rows and columns.

Common Mistake: Incorrect Slicing Syntax

The error often arises from using incorrect syntax without .iloc or .loc:

import pandas as pd

data = {
    'id': [1, 2, 3, 4],
    'name': ['Alice', 'Bob', 'Carl', 'Dan'],
    'salary': [100, 50, 75, 150],
    'experience': [5, 7, 9, 13],
    'task': ['dev', 'test', 'ship', 'manage'],
}
df = pd.DataFrame(data)
  • Using df[1:3,:] will throw an exception.
  • Always use .iloc (for integer-based indexing) or .loc (for label-based indexing) when slicing DataFrames.

Conclusion

The TypeError: unhashable type: 'slice' error occurs when you try to slice a dictionary directly, or when you incorrectly slice a Pandas DataFrame.

  • Dictionaries are not sequences and do not support slicing. To get a "slice" of a dictionary, convert its keys, values, or items to a list first.
  • For Pandas DataFrames, always use .iloc (for integer-based indexing) or .loc (for label-based indexing) for slicing.
  • Never try to slice a DataFrame directly using the [] operator with slice objects.

By understanding the correct usage of these methods, you can avoid this error and work effectively with dictionaries and DataFrames.

Navigation