简体   繁体   中英

Python readlines() doesn't function outputs bug in for loop

Intro: I'm a beginner python learning syntax at the moment. I've come across this concept of reading and writing files natively supported by python. I've figured to give it a try and find bugs after attempting looping reading and writing commands. I wanted to randomly pick a name from a name file and then writing it into a new file. My file includes 19239 lines of names, randrange(18238) generates from 0 - 18238, and, supposedly, would read a randomly read a line between 1 - 18239. The problem is that the code that reads and writes works without the for loop but not with the for loop.

My attempt:

from random import randrange
rdname = open("names.dat", "r")
wrmain = open("main.dat", "a")
rdmain = open("main.dat", "r")

for x in range(6):
    nm = rdname.readlines()[randrange(18238)]
    print(str(randrange(18238)) + ": " + nm)
    wrmain.write("\n" + nm)
...

Error code:

Exception has occurred: IndexError
list index out of range

rdname.readlines() exhausts your file handle. Running rdname.readlines() gives you the list of lines the first time, but returns an empty list every subsequent time. Obviously, you can't access an element in an empty list. To fix this, assign the result of readlines() to a variable just once, before your loop.

rdlines = rdname.readlines()
maxval = len(rdlines)
for x in range(6):
    randval = randrange(maxval)
    nm = rdlines[randval]
    print(str(randval) + ": " + nm)
    wrmain.write("\n" + nm)

Also, making sure your random number can only go to the length of your list is a good idea. No need to hardcode the length of the list though -- the len() function will give you that.

I highly recommend you take a look at how to debug small programs. Using a debugger to step through your code is immensely helpful because you can see how each line affects the values of your variables. In this case, if you'd looked at the value of nm in each iteration, it would be obvious why you got the IndexError , and finding out that nm becomes an empty list on readlines() would point you in the direction of the answer.

Good luck with your programming journey.

The readlines() method. Has some non-intuitive behaviour. When you use the readlines() it "dumps" the entire content of the file and returns a list of strings of each line. Thus the second time you call the rdname.readlines()[randrange(18238)] , the rdname file object is completely empty and you actually have an empty list. So functionally you are telling your programme to run [][randrange(18238)] on the second iteration of the loop.

I also took the liberty of fixing the random number call, as the way you had implemented it would mean it would call 2 different random numbers when selecting the name nm = rdname.readlines()[randrange(18238)] and printing the selected name and linenumber print(str(randrange(18238)) + ": " + nm)

...
rdname = open("names.dat", "r")
wrmain = open("main.dat", "a")
rdmain = open("main.dat", "r")

rdname_list = rdname.readlines()

for x in range(6):
    rd_number = randrange(18238)
    nm = rdname_list[rd_number]
    print(str(rd_number) + ": " + nm)
    wrmain.write("\n" + nm)
...

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