How to Solve "TypeError: unhashable type: 'slice'" in Python
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,
}
# ⛔️ TypeError: unhashable type: 'slice'
# print(a_dict[:2]) # Dictionaries are NOT sliceable like this!
- The attempt to slice
a_dict
using[:2]
directly causes theTypeError
.
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,
}
# Get a slice of the KEYS:
keys_slice = list(a_dict.keys())[:2] # Convert keys to a list, then slice
print(keys_slice) # Output: ['id', 'name']
# Get a slice of the VALUES:
values_slice = list(a_dict.values())[:2] # Convert values to a list, then slice
print(values_slice) # Output: [1, 'Tom Nolan']
# Get a slice of the ITEMS (key-value pairs):
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')]
# If you want a *dictionary* as the result:
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 usinglist()
. - 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)
# Correct: Select rows 1 and 2 (index 1 up to, but not including, 3), and ALL columns
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)
# ⛔️ TypeError: unhashable type: 'slice'
# print(df[1:3, :]) # INCORRECT - mixing slicing with direct access
- 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.