简体   繁体   中英

Index error when reading txt file

I'm new to python, and doing some elementary coding assignments on edx with the Jupityr notebook. I've encountered an index error on one of my assignments I can't quite figure out. The assignment has me read a text file one line at a time within a while loop, and print the output in a specific format. My code is as follows

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(',')

The code runs through the entire file, but instead of ending the 'while' loop at the empty line, it continues to run and create an empty list. I'm not sure why this is happening and can't figure out a fix on my own. I've tried adding an 'if' test for an empty string and breaking, and also writing an additional line of empty text but neither option resulted in any success. If anybody has an idea I would greatly appreciate it!

I have an excerpt of what the txt file contains pasted below as well. There's additional cities, but I don't find it necessary to include every one:

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

This is the index error I was getting: (sorry for poor formatting, still learning


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

I believe you need to check for empty list and not empty string

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

A better (more pythonic?) way to accomplish this would be:

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

You can read a file line by line by using the file object as an iterator. This one shouldn't need the try block as the loop will end gracefully when it reaches an empty line. Also, put this code in a with statement:

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

to make sure the file closes when you're done reading it.

Check out: https://docs.python.org/3/tutorial/inputoutput.html

To clarify what's actually going on in the question:

When readline() reaches the end of a file, it returns an empty string. When you use strip() on an empty string, it returns an empty list. When you use strip(',') or any separator on an empty string it returns a list with an empty string in it. In this case, your while loop was checking the list. Since the list wasn't empty, it returned True and the while loop continued. If you need the while loop, my recommendation would be:

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

This is probably the cleanest way to while loop your way through a file line by line. Pretty much does exactly the same thing as the for loop above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM