python - type - simplejson load string




Por que estou vendo "TypeError: os índices de string devem ser números inteiros"? (4)

TypeError para Notação de Fatia str[a:b]

tl; dr: usa dois pontos : invés de uma vírgula entre os dois índices b em str[a:b]

Ao trabalhar com strings e notação de fatia (uma operação de seqüência comum ), pode acontecer que um TypeError seja gerado, indicando que os índices devem ser números inteiros, mesmo que sejam obviamente.

Exemplo

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

Nós obviamente passamos dois inteiros para os índices para a notação de fatia, certo? Então, qual é o problema aqui?

Esse erro pode ser muito frustrante - especialmente no início do aprendizado do Python - porque a mensagem de erro é um pouco enganosa.

Explicação

Nós implicitamente passamos uma tupla de dois inteiros (0 e 5) para a notação de fatia quando chamamos my_string[0,5] porque 0,5 (mesmo sem os parênteses) é avaliado na mesma tupla que (0,5) faria.

Uma vírgula , na verdade , é suficiente para o Python avaliar algo como uma tupla:

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

Então o que fizemos lá, desta vez explicitamente:

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

Agora, pelo menos, a mensagem de erro faz sentido.

Solução

Precisamos substituir a vírgula , com dois pontos : para separar os dois inteiros corretamente:

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

Uma mensagem de erro mais clara e útil poderia ter sido algo como:

TypeError: string indices must be integers (not tuple)

Uma boa mensagem de erro mostra ao usuário diretamente o que ele fez de errado e teria sido mais óbvio como resolver o problema.

[Então, da próxima vez que você se considerar responsável por escrever uma mensagem de descrição de erro, pense neste exemplo e adicione a razão ou outras informações úteis à mensagem de erro para permitir que você e talvez outras pessoas entendam o que deu errado.]

Lições aprendidas

  • notação de fatia usa dois pontos : para separar seus índices (e intervalo de passos, por exemplo, str[from:to:step] )
  • as tuplas são definidas por vírgulas (por exemplo, t = 1, )
  • adicionar algumas informações às mensagens de erro para os usuários entenderem o que deu errado

Felicidades e programação feliz
winklerrr

[Eu sei que esta pergunta já foi respondida e esta não era exatamente a pergunta que o iniciador de linha perguntou, mas eu vim aqui por causa do problema acima que leva à mesma mensagem de erro. Pelo menos demorei algum tempo para encontrar aquele pequeno erro de digitação.

Então, espero que isso ajude alguém que tropeçou no mesmo erro e economizou algum tempo para encontrar esse pequeno erro.]

Estou brincando com o Python de aprendizado e tentando colocar os problemas do github em um formato legível. Usando os conselhos sobre Como converter JSON em CSV? Eu vim com isso:

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"]])

Onde "issues.json" é o arquivo json contendo meus problemas no github. Quando tento correr isso, fico

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

O que estou perdendo aqui? Quais são os "índices de string"? Tenho certeza de que assim que eu conseguir esse trabalho, terei mais problemas, mas, por enquanto, adoraria que isso funcionasse!

ATUALIZAÇÃO: Quando eu ajustar a declaração for para simplesmente

for item in data:
    print item

o que eu recebo é ... "problemas" - então estou fazendo algo mais errado. Aqui está um pouco do meu 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...

quando eu imprimir data parece que está ficando muito estranhamente:

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

Isso pode acontecer se um comum estiver faltando. Eu corri para ele quando tinha uma lista de duas tuplas, cada uma consistindo de uma string na primeira posição e uma lista na segunda. Eu erroneamente omiti a vírgula após o primeiro componente de uma tupla em um caso, e o interpretador pensou que eu estava tentando indexar o primeiro componente.


data é um objeto dict . Então, iterar sobre isso assim:

Python 2

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

Python 3

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

item é provavelmente uma string no seu código; os índices de string são os que estão entre colchetes, por exemplo, gravatar_id . Então eu primeiro verificaria sua variável de data para ver o que você recebeu lá; Eu acho que os data são uma lista de seqüências de caracteres (ou pelo menos uma lista contendo pelo menos uma seqüência), enquanto deve ser uma lista de dicionários.





github