Fix TypeError: unhashable type: ‘slice’ in Python

Quick answer: The unhashable-slice error usually means slicing syntax was applied to a dictionary rather than a sequence. Check the data type first, then use sequence slicing, nested indexing, or an array library’s multidimensional selector as appropriate.

Python unhashable slice infographic comparing sequence slices, dictionary keys, nested list indexes, and NumPy multidimensional selection
A slice belongs in a sequence or array selector; a dictionary lookup expects a hashable key and does not support ordinary slicing.

TypeError: unhashable type: 'slice' usually means Python received a slice object, such as : or 1:3, in a place that expects a hashable key. The most common cause is trying to slice a dictionary like a list. Dictionaries are mappings, so you select values by key instead of by position.

Quick Fix

If the failing code looks like data[:2] and data is a dictionary, convert the keys or items to a list first, or select explicit keys. If the failing object is a pandas DataFrame, use .iloc for integer-position slicing or .loc for label-based selection.

data = {"name": "Ada", "role": "Developer", "city": "London"}

# Wrong for a dictionary: data[:2]
first_two_items = list(data.items())[:2]

print(first_two_items)

The key idea is to confirm the object type before choosing the indexing syntax. Lists and tuples support positional slicing. Dictionaries support key lookup. DataFrames have their own indexers.

Why a Slice Can Trigger TypeError

Python raises TypeError when an operation is applied to an object of an inappropriate type. A slice is the object created by syntax such as start:stop; Python also exposes it through the built-in slice() function. Dictionary keys must be hashable, and the Python glossary defines hashable objects as objects with a hash value that does not change during their lifetime.

part = slice(0, 2)
print(part)
print(type(part))

# This raises TypeError because a slice is not a valid dict key here.
# print({"a": 1, "b": 2}[part])

That is why the message mentions slice. The colon syntax is being interpreted as a slice object, but the target object is trying to use it as a mapping key.

Python Pool infographic showing dictionary, slice object, bracket access, unhashable key, and TypeError
A dictionary key must be hashable; a slice object is not a valid mapping key in this access pattern.

Fix Dictionary Slicing

Dictionaries are documented as mapping types. They preserve insertion order in modern Python, but they still do not become list-like sequences. If you need the first few keys, values, or items, convert the relevant view to a list and slice that list.

settings = {
    "debug": True,
    "timeout": 30,
    "retries": 3,
}

first_keys = list(settings.keys())[:2]
first_values = list(settings.values())[:2]
first_items = list(settings.items())[:2]

print(first_keys)
print(first_values)
print(first_items)

Use this when order matters and you intentionally want a positional subset. If you know the key name, direct lookup is clearer and faster than converting the dictionary to a list.

Fix pandas DataFrame Slicing

In pandas, choose the indexer that matches your intent. The official DataFrame.iloc documentation describes integer-location based selection. The official DataFrame.loc documentation covers label-based selection.

import pandas as pd

df = pd.DataFrame({
    "name": ["Ada", "Grace", "Linus"],
    "score": [95, 98, 91],
})

first_two_rows = df.iloc[:2]
name_column = df.loc[:, "name"]

print(first_two_rows)
print(name_column)

This is a common fix when code uses DataFrame syntax in a context where the object is actually a plain dictionary or JSON-like data. Check type(obj) before applying pandas indexing.

Python Pool infographic comparing list or string sequence, start stop slice, and selected subsequence
Slices are designed for sequence types such as lists, tuples, strings, and ranges.

Fix JSON-Like Data

Parsed JSON in Python often becomes a mix of dictionaries and lists. You can slice the list parts, but not the dictionary parts. Access dictionary keys first, then slice a list value if that value is actually a list.

payload = {
    "users": [
        {"name": "Ada"},
        {"name": "Grace"},
        {"name": "Linus"},
    ]
}

first_two_users = payload["users"][:2]
print(first_two_users)

If you get the error in web-scraping or API code, print the structure you received. Many bugs come from assuming a response is a list when the outer object is a dictionary with a list nested under one key.

Use itertools.islice for Iterators

Some objects are iterable but do not support normal slicing. In those cases, itertools.islice can take a positional subset without converting the entire iterable first.

from itertools import islice

numbers = (n * n for n in range(10))
first_three = list(islice(numbers, 3))

print(first_three)

Use islice for generators and other iterators. Use normal list slicing for lists. Use explicit keys for dictionaries.

Which Syntax Should You Use?

Use obj[start:stop] only when the object supports slicing, such as a list, tuple, string, or pandas indexer. Use dict[key] when the object is a dictionary and the key name is known. Use list(dict.items())[start:stop] only when you truly need a positional subset of dictionary data. For pandas, prefer df.iloc[start:stop] when you mean row positions and df.loc[:, "column"] when you mean a named column.

This distinction prevents a common debugging trap: the same square brackets can mean very different things depending on the object. The fix is not to remove the colon everywhere; it is to match the colon syntax to an object that supports slicing.

Python Pool infographic comparing dictionary key lookup, nested data, list value, and explicit traversal
For nested data, perform mapping lookup and sequence slicing in separate steps that match each value's type.

Debug Checklist

  • Print type(obj) on the object being sliced.
  • If it is a dictionary, select keys or convert keys(), values(), or items() to a list first.
  • If it is a pandas DataFrame, use .iloc for positions and .loc for labels.
  • If it is JSON-like data, access the list inside the dictionary before slicing.
  • If it is an iterator, use itertools.islice.

Summary

TypeError: unhashable type: 'slice' is a sign that slicing syntax reached an object that expects hashable keys. Do not slice dictionaries directly. Convert dictionary views to lists when you truly need a positional subset, use pandas .iloc or .loc for DataFrames, and inspect nested JSON before slicing.

Dictionary Lookups Are Not Slices

A dictionary lookup such as data[1:3] treats the slice expression as a key. On Python versions where slice objects are unhashable, that produces this error; even where slices are hashable, it is still a dictionary key lookup, not a range operation. Convert the data to a sequence or select explicit dictionary keys.

records = {0: "zero", 1: "one", 2: "two"}
print([records[index] for index in range(1, 3)])
print(list(records.items())[1:3])
Python Pool infographic testing list keys, tuple keys, slices, nested containers, and validation
Check whether the object is a mapping or sequence, whether keys are hashable, and the type at each nesting level.

Use The Matching Selector

Lists and tuples accept start:stop:step slices. A regular nested list does not interpret a comma-separated row-and-column selector as a matrix operation, so index one level at a time. NumPy arrays are designed for tuple-based multidimensional slicing.

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

import numpy as np
array = np.array(matrix)
print(array[:, 1])

Check Version-Specific Details

Python 3.12 made slice objects hashable when their start, stop, and step components are hashable. That changes whether a slice can technically be used as a dictionary key, not whether a dictionary supports slicing. The durable fix is to use the data structure’s documented access model.

items = ["a", "b", "c", "d"]
print(items[1:3])
print(slice(1, 3).indices(len(items)))

Python’s slicing rules explain how a slice becomes an object passed to __getitem__().

For related indexing errors, compare two-dimensional list access, converting arrays to lists, and list index boundaries.

Frequently Asked Questions

Why does Python say unhashable type: slice?

A common cause is using dictionary syntax such as data[1:3], which tries to use a slice object as a dictionary key instead of slicing a sequence.

How do I slice a Python list?

Use list[start:stop:step] with a list or another sequence; a normal list accepts slice objects for indexing.

How do I select rows and columns from a nested list?

Index one level at a time, such as matrix[row][column], or use NumPy when tuple-based multidimensional slicing is required.

Are slice objects hashable in every Python version?

Slice objects became hashable in Python 3.12 when their components are hashable, but dictionaries still do not gain general slice syntax; use a sequence or array API for slicing.

Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted