Python: 'string indices must be integers' — как исправить ошибку быстро
-
Ошибка ‘string indices must be integers’ в Python возникает, когда вы пытаетесь обратиться к элементу строки по строковому ключу вместо числа. Это частая проблема при работе со строками, словарями и JSON. В этой статье разберем, почему она появляется и как ее исправить за минуту.
Знание причин поможет избежать подобных ошибок в будущем. Мы пройдемся по типичным сценариям, разберем код и дадим готовые решения. После прочтения вы сможете диагностировать и чинить такие баги самостоятельно.
Почему Python требует целые индексы для строк
Строки в Python — это последовательности символов, к которым можно обращаться т��лько по целым числам (индексам). Попытка использовать строку как индекс приводит к TypeError. Например, если у вас есть
s = "hello", тоs["h"]вызовет ошибку, потому что Python ожидает число вродеs.Часто ошибка маскирует путаницу между строкой и словарем. Словарь позволяет ключи-строки (
dict["key"]), но строка — нет. Это типичная ловушка при парсинге данных из API или JSON. Рассмотрим реальный пример: вы получаете ответ от сервера как строку, но обращаетесь к ней как к dict.my_string = "hello" # ❌ Ошибка! print(my_string["h"]) # TypeError: string indices must be integersВот что происходит шаг за шагом:
- Python проверяет тип объекта перед индексацией.
- Для строк допустимы только
intилиslice(срезы вродеs). - Любое другое (строка, список, кортеж) вызывает TypeError.
Основные причины ошибки:
- Обращение к строке строковым ключом.
- Парсинг JSON, где ожидается dict, а приходит строка.
- Смешение типов данных из API или файлов.
Ошибка при работе с JSON и API
При парсинге JSON данные часто приходят как словарь, но иногда поле оказывается строкой. Представьте: API возвращает
{"name": "Alice"}, но вы пишетеdata["name"]["first"]. Python думает, чтоdata["name"]— это вложенный dict, а на деле это строка “Alice”.Типичный сценарий — запрос к внешнему сервису. Код загружает JSON, но без проверки типов ломается на вложенном доступе. Это особенно часто случается с нестабильными API, где структура ответа меняется.
Пример проблемного кода:
data = {"name": "Alice", "age": 30} print(data["name"]["first"]) # ❌ TypeError!Шаги для исправления:
- Проверьте тип:
print(type(data["name"])). - Если строка — работайте с индексами:
data["name"]. - Для вложенных структур используйте
get()с проверкой.
Ситуация Неправильно Правильно Простая строка s["a"]sJSON dict str["key"]json.loads(str)["key"]API ответ resp["data"]["id"]resp.get("data", {}).get("id")Нюанс: Всегда добавляйте
json.loads()для строковых ответов API.Срезы строк и путаница с кортежами
Иногда ошибка возникает из-за неправильных скобок в срезах. Python интерпретирует запятую
,как кортеж, а не срез. Например,mystring[0, 5]воспринимается как индексация кортежем(0, 5), что недопустимо для строк.Рассмотрим пример: вы хотите взять подстроку
mystring, но случайно ставите запятую. Python выдает TypeError, потому что ожидает один индекс или срез с двоеточием. Это мелкая, но частая оплошность при копировании кода.Проблемный код:
mystring = "gratitude" print(mystring[0, 5]) # ❌ TypeError: string indices must be integers (tuple)Правильные варианты:
- Срез:
mystring→'grati'. - Одиночный индекс:
mystring→'g'. - Полный срез:
mystring[:]→ вся строка.
Правила для скобок в строках:
[число]— один символ.- `` — подстрока.
[:конец]или[начало:]— с начала/до конца.- Никогда не ставьте запятые внутри
[]!
Проверки типов перед индексацией
Лучшая защита — проверка типов с помощью
type()илиisinstance(). Перед обращением по ключу убедитесь, что объект — словарь или список, а не строка. Это спасет от ошибок в динамических данных вроде CSV, PyTorch датасетов или Google Cloud.В реальных проектах данные часто приходят непредсказуемыми. Например, в PyTorch датасете из CSV
maskможет оказаться строкой вместо numpy-массива. Аналогично в Google Cloudbucket.exists()иногда возвращает JSON-строку.obj = "some string" if isinstance(obj, str): print(obj) # Безопасно elif isinstance(obj, dict): print(obj.get("key"))Рекомендации по отладке:
- Добавьте
print(type(variable))перед ошибочным местом. - Используйте
isinstance(variable, str)для строк. - Для dict —
if "key" in variable:. - В Jupyter добавьте
%debugпосле ошибки.
Тип объекта Допустимые индексы Пример str int, slice s,sdict str, int d["key"],dlist int, slice lst,lstВажно: В вложенных структурах проверяйте каждый уровень.
Ключевые приемы для надежного кода
Ошибку легко предотвратить, если выработать привычки: парсить JSON явно, проверять типы и использовать safe-методы вроде
get(). В больших проектах добавьте type hints сtyping.Dict[str, Any]. Это сделает код устойчивым к изменениям API.Подумать стоит над обработкой edge-кейсов: пустые строки, None вместо dict, неожиданные типы из внешних библиотек. Такие баги часто всплывают в продакшене под нагрузкой.
Здравствуйте! Похоже, вас заинтересовала эта беседа, но у вас ещё нет аккаунта.
Надоело каждый раз пролистывать одни и те же посты? Зарегистрировав аккаунт, вы всегда будете возвращаться на ту же страницу, где были раньше, и сможете выбирать, получать ли уведомления о новых ответах (по электронной почте или в виде push-уведомлений). Вы также сможете сохранять закладки и ставить лайки постам, чтобы выразить свою благодарность другим участникам сообщества.
С вашими комментариями этот пост мог бы стать ещё лучше 💗
Зарегистрироваться Войти© 2024 - 2026 ExLends, Inc. Все права защищены.