Je joue à la fois avec python et j'essaie de rendre lisibles les problèmes de github. En utilisant les conseils sur Comment puis-je convertir JSON en CSV? Je suis arrivé avec ceci:
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"]])
Où "issues.json" est le fichier json contenant mes problèmes de github. Quand j'essaye de courir ça, je reçois
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
Qu'est-ce que j'oublie ici? Quels sont les "indices de chaîne"? Je suis sûr qu'une fois que cela fonctionnera, j'aurai plus de problèmes, mais pour l'instant, j'adorerais que cela fonctionne!
UPDATE: Quand je modifie la déclaration for
simplement
for item in data:
print item
ce que j’obtiens, c’est ... des "problèmes" - alors je fais quelque chose de plus faux. Voici un peu de mon 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...
quand j'imprime data
on dirait que ça devient vraiment étrange:
{u'issues': [{u'body': u'Add missing paging (Older>>) lin...
item
est très probablement une chaîne dans votre code; les indices de chaîne sont ceux entre crochets, par exemple, gravatar_id
. Donc, je vérifie d’abord votre variable data
pour voir ce que vous avez reçu là; Je suppose que data
est une liste de chaînes (ou au moins une liste contenant au moins une chaîne), alors qu'il devrait s'agir d'une liste de dictionnaires.
La variable item
est une chaîne. Un index ressemble à ceci:
>>> mystring = 'helloworld'
>>> print mystring[0]
'h'
L'exemple ci-dessus utilise l'index 0
de la chaîne pour faire référence au premier caractère.
Les chaînes ne peuvent pas avoir d’index (comme les dictionnaires). Donc ça ne marchera pas:
>>> mystring = 'helloworld'
>>> print mystring['stringindex']
TypeError: string indices must be integers
data
est un objet dict
. Alors, parcourez-le comme ceci:
for key, value in data.iteritems():
print key, value
for key, value in data.items():
print(key, value)
str[a:b]
tl; dr: utilisez deux points :
au lieu de une virgule entre les deux index a
et b
dans str[a:b]
Lorsque vous travaillez avec des chaînes et la notation de la tranche (a commun opération de séquence ), il peut arriver qu'une TypeError
soit levée, indiquant que les index doivent être des entiers, même s'ils le sont manifestement.
>>> my_string = "hello world"
>>> my_string[0,5]
TypeError: string indices must be integers
Nous avons évidemment passé deux entiers pour les indices à la notation de tranche, non? Alors, quel est le problème ici?
Cette erreur peut être très frustrante, surtout au début de l'apprentissage Python - car le message d'erreur est un peu trompeur.
Nous avons implicitement passé un tuple de deux entiers (0 et 5) à la notation de tranche lorsque nous avons appelé my_string[0,5]
parce que 0,5
( même sans les parenthèses) correspond au même tuple que (0,5)
.
Une virgule ,
est en fait suffisante pour que Python évalue quelque chose comme un tuple:
>>> my_variable = 0,
>>> type(my_variable)
<class 'Tuple'>
Donc, ce que nous avons fait là, cette fois explicitement:
>>> my_string = "hello world"
>>> my_Tuple = 0, 5
>>> my_string[my_Tuple]
TypeError: string indices must be integers
Maintenant, au moins, le message d'erreur a du sens.
Nous devons remplacer la virgule ,
par un deux-points :
pour séparer correctement les deux entiers:
>>> my_string = "hello world"
>>> my_string[0:5]
'hello'
Un message d'erreur plus clair et plus utile aurait pu être quelque chose comme:
TypeError: string indices must be integers (not Tuple)
Un bon message d'erreur indique directement à l'utilisateur ce qu'il a mal fait et il aurait été plus facile de résoudre le problème.
[Ainsi, la prochaine fois que vous vous retrouverez responsable de la rédaction d'un message de description d'erreur, pensez à cet exemple et ajoutez la raison ou d'autres informations utiles au message d'erreur pour vous permettre, ainsi qu'à d'autres personnes, de comprendre ce qui s'est mal passé.]
:
pour séparer ses index (et sa plage de pas, par exemple str[from:to:step]
),
(par exemple t = 1,
)Vive et bonne programmation
winklerrr
[Je sais que cette question a déjà été répondue et que ce n'était pas exactement la question posée par le démarreur de thread, mais je suis venu ici à cause du problème ci-dessus qui conduit au même message d'erreur. Au moins, il m'a fallu un certain temps pour trouver cette petite faute de frappe.
J'espère donc que cela aidera quelqu'un d'autre qui est tombé sur la même erreur et lui fait gagner un peu de temps en trouvant cette petite erreur.]
Cela peut arriver s'il manque une virgule. Je l'ai rencontré quand j'avais une liste de deux tuples, chacun consistant en une chaîne dans la première position et une liste dans la seconde. J'ai omis par erreur la virgule après le premier composant d'un Tuple dans un cas, et l'interprète pensait que j'essayais d'indexer le premier composant.