Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

'int' object is not subscriptable

+4 votes

Bonjour à tous,

j'étais entrain de suivre le tuto de Sam (lien_ici ) et je bloque sur cet erreur et ne comprends pas pourquoi.
j'ai un peu réadapté la requête pour python3

#module file:
import csv
import urllib.request
import json

from io import StringIO
from datetime import datetime

DATA_SOURCE_URL = "http://data.stackexchange.com/StackOverflow/csv/109782"
QUESTION_URL = "http://stackoverflow.com/questions/{id}"

def download_questions(url=DATA_SOURCE_URL):
    csv_data = StringIO(urllib.request.urlopen(url).read(100000).decode('utf8'))
    for question in csv.DictReader(csv_data):
        question['CreationDate'] = datetime.strptime(question['CreationDate'],
                                                '%Y-%m-%d %H:%M:%S')
        question['Post Link'] = json.loads(question['Post Link'])
        question['Post Link']['url'] = QUESTION_URL.format(id=question['Post Link']['id'])
        yield question

Et ici j'appel le module

for question in download_questions():
    print("{titre}: {url}".format(**question['Post Link']))

Et j'ai ce message d'erreur :

Traceback (most recent call last):
  File "<pyshell#64>", line 1, in <module>
    for question in download_questions():
  File "/Users/blablator/test_python/csv_data2.py", line 24, in download_questions
    question['Post Link']['url'] = QUESTION_URL.format(id=question['Post Link']['id'])
TypeError: 'int' object is not subscriptable

Pourriez vous m'aider à comprendre svp ?

Merci à vous.

demandé 21-Jun-2015 par FredWarning (228 points)

Commence par faire à la fin de ton code un :

print(type(question))

Et dis nous qu'est-ce que ça donne.

1 Réponse

+4 votes

C'est parce que question['Post Link'] est un entier (et non un dictionnaire); ça bug au niveau de: question['Post Link']['id']
Le format de la source (DATASOURCEURL) a peut-être changé depuis le post de Sam ?

répondu 21-Jun-2015 par francoisb

si Sam passe par là ça serait cool :-)

En effet le format à changé. Je vais corriger l'article. Néanmoins c'est quelque chose de très facile à corriger. Fait juste un print(question) et tu verras que question['Post Link'] contient un entier. Parti de là, il te suffit de modifier légèrement la ligne 25 pour que ça marche.

juste un print(type(question)) ne marche pas.
même en commentant le yield , nada :-(

@FredXXX

Il serait judicieux que tu nous montres l'erreur une fois que t'as implémenté le print ;)

ne marche pas.

n'est pas un message d'erreur très pratique afin que nous puissions t'aider :x

import csv
import urllib.request
import json

from io import StringIO
from datetime import datetime

#l'url du CSV
DATA_SOURCE_URL = "http://data.stackexchange.com/StackOverflow/csv/109782"
QUESTION_URL = "http://stackoverflow.com/questions/{id}"

def download_questions(url=DATA_SOURCE_URL):
    csv_data = StringIO(urllib.request.urlopen(url).read(100000).decode('utf8'))
    for question in csv.DictReader(csv_data):

        # On transforme la chaîne date en objet datetime
        question['CreationDate'] = datetime.strptime(question['CreationDate'],
                                                   '%Y-%m-%d %H:%M:%S')
        # le deuxième champ est au format JSON
        # alors on le transforme en objet Python
        question['Post Link'] = json.loads(question['Post Link'])

        # On ajoute l'url de la question généré à partir de l'ID
        question['Post Link']['url'] = QUESTION_URL.format(id=question['Post Link']['id'])

        print(type(question))       
        #yield int(question)

Et ça donne toujours:

Traceback (most recent call last):
  File "<pyshell#26>", line 1, in <module>
    download_questions()
  File "/Users/blablator/test_python/csv_data2.py", line 24, in download_questions
    question['Post Link']['url'] = QUESTION_URL.format(id=question['Post Link']['id'])
TypeError: 'int' object is not subscriptable

ok, vire la ligne qui bug, et réessaye =D, le pb c'est que la ligne qui bug stop l'exécution de ton programme, du coup t'arrive jamais au print.

Donc, dans un premier temps, occupe toi de ça,

Comme précisé par @francoisb, le deuxième champs n'est pas un dictionnaire sérialisé en json, mais un entier (sérialisé en json)

Du coup après

    question['Post Link'] = json.loads(question['Post Link'])

question['Post Link'] ne contient pas un dico, mais un entier.

Un affectation du style

question['Post Link']['url'] = something

n'auras aucune chance de marcher ;)

...