2017-06-22 3 views
0

Je suis novice en python et j'effectue des tâches de codage élémentaires sur edx avec le bloc-notes Jupityr. J'ai rencontré une erreur d'index sur l'une de mes missions que je n'arrive pas à comprendre. L'affectation m'a fait lire un fichier texte une ligne à la fois dans une boucle while, et imprimer la sortie dans un format spécifique. Mon code est le suivantErreur d'index lors de la lecture du fichier txt

city_temp = mean_temp.readline().strip().split(',') 

while city_temp: 

    print (headings[0].title(), "of", city_temp[0], headings[2], "is", city_temp[2], "Celsius") 
    city_temp = mean_temp.readline().strip().split(',') 

Le code passe par le fichier entier, mais au lieu de mettre fin à la « tout » boucle à la ligne vide, il continue de fonctionner et de créer une liste vide. Je ne suis pas sûr de ce qui se passe et je n'arrive pas à trouver une solution par moi-même. J'ai essayé d'ajouter un test 'if' pour une chaîne vide et une rupture, et aussi d'écrire une ligne supplémentaire de texte vide mais aucune de ces options n'a abouti. Si quelqu'un a une idée, je l'apprécierais grandement!

J'ai un extrait de ce que le fichier txt contient aussi collé ci-dessous. Il y a des villes supplémentaires, mais je ne trouve pas nécessaire d'inclure tous:

city,country,month ave: highest high,month ave: lowest low 
Beijing,China,30.9,-8.4 

Ceci est l'erreur d'index que je recevais: (désolé pour le pauvre mise en forme, l'apprentissage encore


IndexError        Traceback (most recent call last) 
<ipython-input-18-6ea7e8e263b5> in <module>() 
     5 while city_temp: 
     6 
----> 7  print (headings[0].title(), "of", city_temp[0], headings[2], "is", city_temp[2], "Celsius") 
     8  city_temp = mean_temp.readline().strip().split(',') 
     9 

IndexError: list index out of range 
+0

Pour résoudre réellement votre IndexError, modifiez dans votre question votre message d'erreur entier, y compris le retraçage. city_temp devrait être une liste vide s'il lit une ligne vide (strip() supprimerait tous les caractères d'espaces avant que le split ne se produise), donc il se passe quelque chose d'autre ici. –

+0

@AlanLeuthard J'ai joint toute l'erreur que je recevais avant, je suis très curieux de comprendre pourquoi cette erreur se produit – thatbrownkid

+0

Ahhhh ... juste testé. 'empty_string.split()' retourne une liste vide. 'empty_string.split (', ')' renvoie une liste avec une chaîne vide. La liste n'est pas vide, donc city_temp est True. Changez 'while city_temp' en 'while city_temp [0]' pour vérifier le vide de ce qui est dans la liste. Ou utilisez un bloc try. –

Répondre

0

Une meilleure façon d'y arriver w (plus pythonique?) ould être:

for line in mean_temp: 
    city_temp = line.strip().split(',') 
    try: 
     print ("{} of {} {} is {} Celsius".format(headings[0].title(), 
                city_temp[0], 
                headings[2], 
                city_temp[2])) 
    except IndexError: 
     break 

Vous pouvez lire une ligne de fichiers en ligne en utilisant l'objet de fichier en tant que iterator. Celui-ci ne devrait pas avoir besoin du bloc try car la boucle se termine normalement quand elle atteint une ligne vide. En outre, mettre ce code dans une déclaration avec:

with open("myfile.txt", 'r') as mean_temp: 

pour vérifier que le fichier se ferme lorsque vous avez terminé la lecture.

Départ: https://docs.python.org/3/tutorial/inputoutput.html

Pour clarifier ce qui se passe réellement dans la question:

Lorsque readline() atteint la fin d'un fichier, il retourne une chaîne vide. Lorsque vous utilisez strip() sur une chaîne vide, elle renvoie une liste vide. Lorsque vous utilisez strip (',') ou un séparateur sur une chaîne vide, elle renvoie une liste avec une chaîne vide. Dans ce cas, votre boucle while vérifiait la liste. Comme la liste n'était pas vide, elle renvoyait True et la boucle while continuait. Si vous avez besoin de la boucle while, ma recommandation serait:

line = mean_temp.readline() 
while line: 
    city_temp = line.strip().split(',') 
    print ("{} of {} {} is {} Celsius".format(headings[0].title(), 
               city_temp[0], 
               headings[2], 
               city_temp[2])) 
    line = mean_temp.readline() 

C'est probablement la façon la plus propre à boucle while votre chemin à travers une ligne de fichiers en ligne. Pratiquement fait exactement la même chose que la boucle for ci-dessus.

+0

C'est une bonne idée, merci pour le pourboire! Malheureusement, la soumission que je fais nécessite la présence de la boucle while, mais je vais certainement utiliser la commande try à l'avenir. – thatbrownkid

+0

Conservez ensuite les conditions initiales readline() et while. Utilisez le bloc try: pour votre déclaration d'impression et vous avez terminé. –

+0

fantastique! Merci beaucoup pour votre aide! – thatbrownkid

0

Je crois que vous devez vérifier la liste vide et non une chaîne vide

city_temp = mean_temp.readline().strip().split(',') 

while city_temp: 

    print (headings[0].title(), "of", city_temp[0], headings[2], "is", city_temp[2], "Celsius") 
    city_temp = mean_temp.readline().strip().split(',') 
    if len(city_temp) == 0: 
    break 
+0

J'ai essayé de le faire, et j'ai toujours l'erreur d'index. IndexError retraçage (appel le plus récent dernier) dans () Je suis d'accord avec votre commentaire que je vérifierai une liste vide mais, je ne sais pas pourquoi je n'y ai pas pensé. – thatbrownkid

+1

Vous recherchez une liste vide. Si "city_temp" est vide, alors il présentera False à la boucle while. La vérification de 0 longueur est en réalité redondante. –