Bienvenue sur IndexError.

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

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

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 ;)

...