Почему я вижу "TypeError: строковые индексы должны быть целыми числами"? - PullRequest
149 голосов
/ 21 мая 2011

Я играю как с изучением Python, так и с тем, чтобы вывести вопросы github в удобочитаемую форму. Используя совет по Как я могу конвертировать JSON в CSV? Я придумал это:

import json
import csv

f=open('issues.json')
data = json.load(f)
f.close()

f=open("issues.csv","wb+")
csv_file=csv.writer(f)

csv_file.writerow(["gravatar_id","position","number","votes","created_at","comments","body","title","updated_at","html_url","user","labels","state"])

for item in data:
        csv_file.writerow([item["gravatar_id"], item["position"], item["number"], item["votes"], item["created_at"], item["comments"], item["body"], item["title"], item["updated_at"], item["html_url"], item["user"], item["labels"], item["state"]])

Где "Issue.json" - это файл json, содержащий мои проблемы с github. Когда я пытаюсь запустить это, я получаю

File "foo.py", line 14, in <module>
csv_file.writerow([item["gravatar_id"], item["position"], item["number"], item["votes"], item["created_at"], item["comments"], item["body"], item["title"], item["updated_at"], item["html_url"], item["user"], item["labels"], item["state"]])

TypeError: string indices must be integers

Что мне здесь не хватает? Каковы "строковые индексы"? Я уверен, что, как только я получу эту работу, у меня будет больше проблем, но сейчас я просто хотел бы, чтобы это сработало!

UPDATE: Когда я настраиваю выражение for на

for item in data:
    print item

что я получаю ... это "проблемы" - так что я делаю что-то более неправильное. Вот немного моего JSON:

{"issues":[{"gravatar_id":"44230311a3dcd684b6c5f81bf2ec9f60","position":2.0,"number":263,"votes":0,"created_at":"2010/09/17 16:06:50 -0700","comments":11,"body":"Add missing paging (Older>>) links...

когда я печатаю data, создается впечатление, что его очень странно портят:

{u'issues': [{u'body': u'Add missing paging (Older>>) lin...

Ответы [ 5 ]

126 голосов
/ 21 мая 2011

Переменная item является строкой. Индекс выглядит так:

>>> mystring = 'helloworld'
>>> print mystring[0]
'h'

В приведенном выше примере используется индекс 0 строки для ссылки на первый символ.

Строки не могут иметь строковые индексы (как словари могут). Так что это не сработает:

>>> mystring = 'helloworld'
>>> print mystring['stringindex']
TypeError: string indices must be integers
83 голосов
/ 21 мая 2011

item скорее всего строка в вашем коде; строковые индексы - это те, которые указаны в квадратных скобках, например, gravatar_id. Поэтому я сначала проверил вашу переменную data, чтобы увидеть, что вы там получили; Я предполагаю, что data - это список строк (или хотя бы список, содержащий хотя бы одну строку), в то время как это должен быть список словарей.

33 голосов
/ 21 мая 2011

data является dict объектом. Итак, переберите его так:

Python 2

for key, value in data.iteritems():
    print key, value

Python 3

for key, value in data.items():
    print(key, value)
17 голосов
/ 30 августа 2018

TypeError для обозначения среза str[a:b]

tl; dr: используйте двоеточие : вместо запятой междудва индекса a и b в str[a:b]


При работе с строками и обозначением среза ( общая операция последовательности), может случиться так, что TypeError будет поднят, указывая, что индексы должны быть целыми числами, даже если они, очевидно, являются.

Пример

>>> my_string = "hello world"
>>> my_string[0,5]
TypeError: string indices must be integers

Мы, очевидно, прошлидва целых числа для индексов для обозначения среза, верно?Так в чем здесь проблема?

Эта ошибка может быть очень неприятной - особенно в начале изучения Python - потому что сообщение об ошибке немного вводит в заблуждение.

Объяснение

Мы неявно передали кортеж из двух целых чисел (0 и 5) в нотацию среза, когда мы вызвали my_string[0,5], потому что 0,5 (даже без скобок) оценивает тот же кортеж, что и (0,5)do.

Запятую , на самом деле достаточно для Python, чтобы оценить что-то как кортеж:

>>> my_variable = 0,
>>> type(my_variable)
<class 'tuple'>

Итак, что мы сделали там, на этот раз явно:

>>> my_string = "hello world"
>>> my_tuple = 0, 5
>>> my_string[my_tuple]
TypeError: string indices must be integers

Теперь, по крайней мере, сообщение об ошибке имеет смысл.

Решение

Нам нужно заменить запятую , на двоеточие : для правильного разделения двух целых чисел:

>>> my_string = "hello world"
>>> my_string[0:5]
'hello'

Более четкое и полезное сообщение об ошибке могло выглядеть примерно так:

TypeError: string indices must be integers (not tuple)

Хорошее сообщение об ошибке показывает пользователя напрямуючто они сделали неправильно, и это было бы болееочень как решить проблему.

[Поэтому в следующий раз, когда вы обнаружите себя ответственным за написание сообщения с описанием ошибки, подумайте об этом примере и добавьте причину или другую полезную информацию в сообщение об ошибке, чтобы позволить вам и другим людям понять, что пошло не так.]

Извлеченные уроки

  • Для обозначения фрагмента используются двоеточия : для разделения его индексов (и диапазон шагов, например, str[from:to:step])
  • кортежи определяются запятыми, (например, t = 1,)
  • добавить некоторую информацию в сообщения об ошибках для пользователей, чтобы понять, что пошло не так

Приветствия и счастливое программирование
winklerrr


[Я знаю, что на этот вопрос уже был дан ответ, и это был не совсем тот вопрос, который задал автор темы, но я пришел сюда из-за вышеуказанной проблемы, которая приводит к тому же сообщению об ошибке.По крайней мере, мне понадобилось некоторое время, чтобы найти эту маленькую опечатку.

Так что я надеюсь, что это поможет кому-то еще, кто наткнулся на ту же ошибку и сэкономит им некоторое время, обнаружив эту крошечную ошибку.]

0 голосов
/ 25 апреля 2017

Это может произойти, если отсутствует общее. Я столкнулся с ним, когда у меня был список из двух кортежей, каждый из которых состоял из строки в первой позиции и списка во второй. В одном случае я ошибочно пропустил запятую после первого компонента кортежа, и интерпретатор подумал, что я пытаюсь проиндексировать первый компонент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...