<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Python: &#x27;string indices must be integers&#x27; — как исправить ошибку быстро]]></title><description><![CDATA[<p dir="auto">Ошибка <strong>‘string indices must be integers’</strong> в Python возникает, когда вы пытаетесь обратиться к элементу строки по строковому ключу вместо числа. Это частая проблема при работе со строками, словарями и JSON. В этой статье разберем, почему она появляется и как ее исправить за минуту.</p>
<p dir="auto">Знание причин поможет избежать подобных ошибок в будущем. Мы пройдемся по типичным сценариям, разберем код и дадим готовые решения. После прочтения вы сможете диагностировать и чинить такие баги самостоятельно.</p>
<h2>Почему Python требует целые индексы для строк</h2>
<p dir="auto">Строки в Python — это последовательности символов, к которым можно обращаться т��лько по <strong>целым числам</strong> (индексам). Попытка использовать строку как индекс приводит к TypeError. Например, если у вас есть <code>s = "hello"</code>, то <code>s["h"]</code> вызовет ошибку, потому что Python ожидает число вроде <code>s</code>.</p>
<p dir="auto">Часто ошибка маскирует путаницу между <strong>строкой</strong> и <strong>словарем</strong>. Словарь позволяет ключи-строки (<code>dict["key"]</code>), но строка — нет. Это типичная ловушка при парсинге данных из API или JSON. Рассмотрим реальный пример: вы получаете ответ от сервера как строку, но обращаетесь к ней как к dict.</p>
<pre><code class="language-python">my_string = "hello"
# ❌ Ошибка!
print(my_string["h"])  # TypeError: string indices must be integers
</code></pre>
<p dir="auto">Вот что происходит шаг за шагом:</p>
<ul>
<li>Python проверяет тип объекта перед индексацией.</li>
<li>Для строк допустимы только <code>int</code> или <code>slice</code> (срезы вроде <code>s</code>).</li>
<li>Любое другое (строка, список, кортеж) вызывает TypeError.</li>
</ul>
<p dir="auto"><strong>Основные причины ошибки:</strong></p>
<ul>
<li>Обращение к строке строковым ключом.</li>
<li>Парсинг JSON, где ожидается dict, а приходит строка.</li>
<li>Смешение типов данных из API или файлов.</li>
</ul>
<h2>Ошибка при работе с JSON и API</h2>
<p dir="auto">При парсинге JSON данные часто приходят как словарь, но иногда поле оказывается строкой. Представьте: API возвращает <code>{"name": "Alice"}</code>, но вы пишете <code>data["name"]["first"]</code>. Python думает, что <code>data["name"]</code> — это вложенный dict, а на деле это строка “Alice”.</p>
<p dir="auto">Типичный сценарий — запрос к внешнему сервису. Код загружает JSON, но без проверки типов ломается на вложенном доступе. Это особенно часто случается с нестабильными API, где структура ответа меняется.</p>
<p dir="auto">Пример проблемного кода:</p>
<pre><code class="language-python">data = {"name": "Alice", "age": 30}
print(data["name"]["first"])  # ❌ TypeError!
</code></pre>
<p dir="auto"><strong>Шаги для исправления:</strong></p>
<ol>
<li>Проверьте тип: <code>print(type(data["name"]))</code>.</li>
<li>Если строка — работайте с индексами: <code>data["name"]</code>.</li>
<li>Для вложенных структур используйте <code>get()</code> с проверкой.</li>
</ol>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Ситуация</th>
<th>Неправильно</th>
<th>Правильно</th>
</tr>
</thead>
<tbody>
<tr>
<td>Простая строка</td>
<td><code>s["a"]</code></td>
<td><code>s</code></td>
</tr>
<tr>
<td>JSON dict</td>
<td><code>str["key"]</code></td>
<td><code>json.loads(str)["key"]</code></td>
</tr>
<tr>
<td>API ответ</td>
<td><code>resp["data"]["id"]</code></td>
<td><code>resp.get("data", {}).get("id")</code></td>
</tr>
</tbody>
</table>
<p dir="auto"><em>Нюанс:</em> Всегда добавляйте <code>json.loads()</code> для строковых ответов API.</p>
<h2>Срезы строк и путаница с кортежами</h2>
<p dir="auto">Иногда ошибка возникает из-за <strong>неправильных скобок</strong> в срезах. Python интерпретирует запятую <code>,</code> как кортеж, а не срез. Например, <code>mystring[0, 5]</code> воспринимается как индексация кортежем <code>(0, 5)</code>, что недопустимо для строк.</p>
<p dir="auto">Рассмотрим пример: вы хотите взять подстроку <code>mystring</code>, но случайно ставите запятую. Python выдает TypeError, потому что ожидает один индекс или срез с двоеточием. Это мелкая, но частая оплошность при копировании кода.</p>
<p dir="auto">Проблемный код:</p>
<pre><code class="language-python">mystring = "gratitude"
print(mystring[0, 5])  # ❌ TypeError: string indices must be integers (tuple)
</code></pre>
<p dir="auto"><strong>Правильные варианты:</strong></p>
<ul>
<li>Срез: <code>mystring</code> → <code>'grati'</code>.</li>
<li>Одиночный индекс: <code>mystring</code> → <code>'g'</code>.</li>
<li>Полный срез: <code>mystring[:]</code> → вся строка.</li>
</ul>
<p dir="auto"><strong>Правила для скобок в строках:</strong></p>
<ul>
<li><code>[число]</code> — один символ.</li>
<li>`` — подстрока.</li>
<li><code>[:конец]</code> или <code>[начало:]</code> — с начала/до конца.</li>
<li>Никогда не ставьте запятые внутри <code>[]</code>!</li>
</ul>
<h2>Проверки типов перед индексацией</h2>
<p dir="auto">Лучшая защита — проверка типов с помощью <code>type()</code> или <code>isinstance()</code>. Перед обращением по ключу убедитесь, что объект — словарь или список, а не строка. Это спасет от ошибок в динамических данных вроде CSV, PyTorch датасетов или Google Cloud.</p>
<p dir="auto">В реальных проектах данные часто приходят непредсказуемыми. Например, в PyTorch датасете из CSV <code>mask</code> может оказаться строкой вместо numpy-массива. Аналогично в Google Cloud <code>bucket.exists()</code> иногда возвращает JSON-строку.</p>
<pre><code class="language-python">obj = "some string"
if isinstance(obj, str):
    print(obj)  # Безопасно
elif isinstance(obj, dict):
    print(obj.get("key"))
</code></pre>
<p dir="auto"><strong>Рекомендации по отладке:</strong></p>
<ul>
<li>Добавьте <code>print(type(variable))</code> перед ошибочным местом.</li>
<li>Используйте <code>isinstance(variable, str)</code> для строк.</li>
<li>Для dict — <code>if "key" in variable:</code>.</li>
<li>В Jupyter добавьте <code>%debug</code> после ошибки.</li>
</ul>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Тип объекта</th>
<th>Допустимые индексы</th>
<th>Пример</th>
</tr>
</thead>
<tbody>
<tr>
<td>str</td>
<td>int, slice</td>
<td><code>s</code>, <code>s</code></td>
</tr>
<tr>
<td>dict</td>
<td>str, int</td>
<td><code>d["key"]</code>, <code>d</code></td>
</tr>
<tr>
<td>list</td>
<td>int, slice</td>
<td><code>lst</code>, <code>lst</code></td>
</tr>
</tbody>
</table>
<p dir="auto"><em>Важно:</em> В вложенных структурах проверяйте каждый уровень.</p>
<h2>Ключевые приемы для надежного кода</h2>
<p dir="auto">Ошибку легко предотвратить, если выработать привычки: парсить JSON явно, проверять типы и использовать safe-методы вроде <code>get()</code>. В больших проектах добавьте type hints с <code>typing.Dict[str, Any]</code>. Это сделает код устойчивым к изменениям API.</p>
<p dir="auto">Подумать стоит над обработкой edge-кейсов: пустые строки, None вместо dict, неожиданные типы из внешних библиотек. Такие баги часто всплывают в продакшене под нагрузкой.</p>
]]></description><link>https://forum.exlends.com/topic/594/python-string-indices-must-be-integers-kak-ispravit-oshibku-bystro</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 22:05:34 GMT</lastBuildDate><atom:link href="https://forum.exlends.com/topic/594.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 20 Feb 2026 07:42:13 GMT</pubDate><ttl>60</ttl></channel></rss>