This is because readlines
reads the entire contents of the file, and when you call it again, there is nothing left to read.
If you want to save lines to use later, just use readlines
only once and save the result in a list, and use this list in the following times:
with open("grades.txt", "r") as f:
linhas = f.readlines()
for record in linhas:
print(f"grade : {record} ")
print(f"readlines: {linhas}")
Note the use of with
, which already ensures that the file will be closed at the end even if any error occurs while reading (so you need not call close
).
Note also that this does not have nothingness to do with "the file be occupied by the program", as he claimed another answer (which has been deleted). What happens is that there is an "inner pointer" that indicates the position you are in the file, and every time you read something from it, that pointer moves forward positions. And how readlines
reads all the content, after calling it this "pointer" will be at the end of the file (so any call made after does not find anything else).
But you can go back to the beginning of the file (using seek
) and read again (although it is not very useful in this case):
with open("grades.txt", "r") as f:
for record in f.readlines() # ler o arquivo uma vez
# ... faz o que quiser com record
f.seek(0) # voltar ao início
print(f.readlines()) # ler de novo
As I said, in this case it doesn’t make any sense to read the file again. Use the first solution, which only reads once and that’s it.
Just one detail: readlines
keeps the file line breaks, so when printing with print(f"grade : {record} ")
, you will end up skipping 2 lines: one referring to the existing line break in the file, and another that the print
automatically adds. That is, the first code will print:
grade: linha 1
grade: linha 2
etc...
If you want to remove these "extra" line breaks, you can change the parameter in the print
, or remove it from the line itself:
for record in linhas:
print(f"grade : {record} ", end="")
# ou
for record in linhas:
record = record.rstrip('\n')
print(f"grade : {record} ")
Remember that in the first case, the last line will not have the line break after (if the last non-empty line of the file does not have a line break). In the second case, all lines will have an added line break.
Another alternative is to already create the list without these line breaks:
with open("grades.txt", "r") as f:
# remove a quebra de linha de todas as linhas
linhas = [ linha.rstrip('\n') for linha in f.readlines() ]
for record in linhas:
print(f"grade : {record} ")
It is also worth remembering that readlines
always loads the entire contents of the file into memory at once, which can be a problem for very large files. If you really need to have a list of all the lines, there’s not much to do. But if you just want to read the lines (and do something with them) and don’t need to keep them, then you better read line by line:
with open("grades.txt", "r") as f:
for linha in f: # assim você lê uma linha de cada vez
# faz o que precisar com a linha