PythonMastery
reference 3 min read · lesson 4 of 45 in Errors

TypeError: list indices must be integers or slices, not str

1 · The lesson

read

What this error means

You indexed a list with a string, like users["name"]. Lists are ordered by position — users[0], users[1] — not by key. You can only use a string subscript on a dict. Python is telling you it expected an integer position (or a slice like users[0:2]) and got a string instead.

When you see it

python
Traceback (most recent call last):
  File "main.py", line 4, in <module>
    name = users["name"]
TypeError: list indices must be integers or slices, not str

Why it happens

Almost always: you got a list of dicts back from json.loads(...), a database query, or an API call, and treated the whole list as if it were a single dict.

python
import json
raw = '[{"name": "alice"}, {"name": "bob"}]'
users = json.loads(raw)        # this is a LIST of dicts, not a dict
print(users["name"])           # TypeError

The fix is almost always "index into the list first, then the dict" — or loop.

How to fix it

Index by position, then by key:

python
users = [{"name": "alice"}, {"name": "bob"}]
print(users[0]["name"])        # "alice"

Loop when you want every element:

python
for user in users:
    print(user["name"])
+ setup added so this can run · defines users
users = [{"name": "alpha"}, {"name": "beta"}, {"name": "gamma"}]

Use a list comprehension to extract a column:

python
names = [u["name"] for u in users]
+ setup added so this can run · defines users
users = [{"name": "alpha"}, {"name": "beta"}, {"name": "gamma"}]

Or restructure the data into a dict-by-id, if you'll be doing many lookups:

python
users_by_id = {u["id"]: u for u in users}
print(users_by_id[42]["name"])
+ setup added so this can run · defines users
users = [{"id": "alpha"}, {"id": "beta"}, {"id": "gamma"}]

When you'd actually see this in real code

  • json.loads(response.text) returned a list, not a dict — you assumed the wrong shape of the API response.
  • A CSV reader (csv.DictReader) gives you an iterable of dicts; you tried reader["column"] instead of looping.
  • An ORM query returned multiple rows; you treated the whole result set as one row.
  • You stored a list in a variable named like a dict (config = [...]) and later wrote config["host"].

See Also