Distinguishing between blank lines and end of file in Python [duplicate] - python

This question already has answers here:
Python: read all text file lines in loop
(5 answers)
Closed 8 years ago.
A situation that I continually run into is the following:
readFile = open("myFile.txt", "r")
while True:
readLine = readFile.readline()
if readLine == "":
#Assume end of file
break
#Otherwise, do something with the line
#...
The problem is that the file I am reading contains blank lines. According to the documentation I have read, file.readline() will return "\n" for a blank line found in a file, but that does not happen for me. If I don't put that blank line condition in the while loop, it continues infinitely, because a readline() executed at or beyond the end of the file returns a blank string.
Can somebody help me create a condition that allows the program to read blank lines, but to stop when it reaches the end of the file?

Just use a for loop:
for readLine in open("myFile.txt"):
print(readLine); # Displayes your line contents - should also display "\n"
# Do something more
Stops automatically at end of file.
If you sometimes need an extra line, something like this might work:
with open("myFile.txt") as f:
for line in f:
if needs_extra_line(line): # Implement this yourself :-)
line += next(f) # Add next line to this one
print(line)
Or a generator that yields the chunks you want to use:
def chunks(file_object):
for line in file_object:
if needs_extra_line(line):
line += next(file_object)
yield line
Then the function that processes the lines can run a for loop over that generator.

Related

Is there a way to get lines of a txt file as an input? [duplicate]

This question already has answers here:
Is it possible to modify lines in a file in-place?
(5 answers)
Closed 2 months ago.
Let's suppose I have a file, demo.txt. This file contains three lines which are:
- line 1
- line 2
- line 3
I want to edit this file lines while iterating the demo.txt. For example, the program started to iterating, and now we are at line 1.
Now we modify this line to line 1.1 and press Enter the continue to iterate to the line 2. When I pressed enter the line 1.1 is saved to demo.txt file.
Then the same thing for line 2, i have changed line 2 to line 2.2 and pressed enter. The same thing for line 3: Change to line 3.3, press Enter to save and finished. This should be apply to every line. Is there a way to achieve that?
Like others explained in comments, you should not read a file while changing its content at the same time. You'll get either bad performance or inconsistent results (or both). You should either buffer the input for reading or buffer the output for writing.
Here is a solution that buffers the input file:
from pathlib import Path
def main():
path = Path("demo.txt")
lines = path.read_text().splitlines()
with path.open("w") as f:
for line in lines:
new_line = transform(line)
f.write(f"{line}\n")
if __name__ == "__main__":
main()
Here, transform is a function that transform a line into a new line. the input file demo.txt is overwritten.
The other way around, i.e. buffering writes, would be:
from pathlib import Path
def main():
path = Path("demo.txt")
new_lines = []
with path.open() as f:
for line in f:
new_line = transform(line)
lines.append(f"{new_line}")
path.write_text("\n".join(new_lines))
if __name__ == "__main__":
main()
Alternatively, you can create a new file with a different name as suggested in another answer.
As I mentioned in comments, we should not save in the same file once the line is processed which you are currently accessing/iterating over. Simply take the two files and open them one at a time and modify accordingly.
import os
with open('demo.txt') as file, open ('new.txt', 'w+') as file2:
for line in file:
s = input()
if len(s) ==0:
line = "modified\n"
file2.write(line)
print(line)
file.close()
file2.close()
os.replace('new.txt', 'demo.txt')
Your new demo.txt file looks like this
modified
modified
modified
What's happening here:
Open your file and a temporary dummy file at once.
Wait for user to hit enter. once he hits enter python reads line1 and saves to new line.
once all the lines are finished, close the both files.
Rename your temporary file with old original file name, i.e,, demo.txt

How does not adding a new line erase lines below it [duplicate]

This question already has answers here:
Writelines writes lines without newline, Just fills the file
(8 answers)
Closed 5 months ago.
f= open('elk.in','r')
lines = f.readlines()
for line in lines:
if line.startswith('vkloff'):
p=lines.index(line)+1
#print(lines[p])
break
lines[p] = f'{string}\n'
string=''
with open('elk.in','w') as out:
out.writelines(lines)
out.close()
Here in lines[p] if I remove \n the lines below it get removed. How does it work then?
Taking a few guesses at what your intent here is. You want to open a file, find a line starting with a given prefix, replace it with something else, then write back to the file? There's a few mistakes here if that's the case
You're trying to open a file you already have open. You should close it first.
string is not defined before you use it, assuming this is the full code.
When opening a file using with, you don't need to close it after.
With these in mind you want something like
with open('elk.in','r') as f:
lines = f.readlines()
for idx, line in enumerate(lines):
if line.startswith('vkloff'):
p = idx
break
lines[p] = f'{string}\n'
with open('elk.in','w') as out:
out.writelines(lines)
But really more information is needed about what you're trying to achieve here.

While in python does not print all the rows

Dear I want display the three rows contained in txt file but I don't know why the following code does not works.
The code is
f=open("dati.txt","r")
riga=f.readline()
while riga!="":
print(f.readline())
riga=f.readline()
f.close()
because you are reading two lines in a loop. The readline moves the cursor one down each time you call it. So what happens there with the second call of readline() you actually skip it(in the print log)
Also checking for end of file should not be done on empty string, because you may hit an empty line before the end of the file. Try this instead:
with open('somefile') as openfileobject:
for line in openfileobject:
do_something()
and or/check this thread(where I copied the snippet from): What is the perfect counterpart in Python for "while not EOF"
The reason why your program is not printing all the rows in the file, but rather only every even numbered row, is because you use f.readline() multiple times in the while statement.
f=open("dati.txt","r")
riga=f.readline() # This line means that the variable "riga" contains the first line in your file
while riga!="":
print(f.readline()) # here you do f.readline() again, which means that what you are printing is the second line
riga=f.readline() # This line reads in the third line into the "riga" variable.
f.close()
What I think you are looking for, is to print the contents of the riga variable instead, like this
while riga != "":
print(riga)
riga = f.readline()
I should also mention that tstoev's answer also has a good approach at printing each line in a file. It does solve the same problem, but it does not point out why your code doesn't work.
Your code reads three lines and prints only one:
f=open("dati.txt","r")
riga=f.readline() # Reads a line into riga
while riga!="":
print(f.readline()) # Reads a line and prints it
riga=f.readline() # Reads a line into riga
f.close()
So the problem seems that you read lines into riga, but never print riga.

Eliminate blank lines in file read Python [duplicate]

This question already has answers here:
Python program prints an extra empty line when reading a text file
(4 answers)
Closed 3 years ago.
I'm trying to read a file into a list using Python. But when I do that the list appears with blank lines after each entry. The source file doesn't have that!
My code:
aws_env_list="../../../source_files/aws_environments/aws_environments_all.txt"
with open(aws_env_list, 'r') as aws_envs:
for line in aws_envs:
print(line)
Each line prints out with a blank line after each entry:
company-lab
company-bill
company-stage
company-dlab
company-nonprod
company-prod
company-eng-cis
The source file looks like this:
company-lab
company-bill
company-stage
company-dlab
company-nonprod
company-prod
company-eng-cis
How do I get rid of the blank line after each entry?
When you iterate over a file line-by-line using:
for line in aws_envs:
The value of line includes the end-of-line character...and the print command, by default, adds an end-of-line character to your output. You can suppress that by setting the end parameter to an empty value. Compare:
>>> print('one');print('two')
one
two
Vs:
>>> print('one', end='');print('two')
onetwo
Your file has a new line character at the end of each line like:
company-lab\n
company-bill\n
company-stage\n
company-dlab\n
company-nonprod\n
company-prod\n
company-eng-cis # not here though this has an EOF (end-of-file) character.
So your call to print(line) is including these in the print! You can avoid this like:
aws_env_list="../../../source_files/aws_environments/aws_environments_all.txt"
with open(aws_env_list, 'r') as aws_envs:
for line in aws_envs.readlines():
print(line.strip()) # just strip the \n away!
UPDATE
If you would like to compute with just the text and not the newline character you can strip it away like this:
aws_env_list="../../../source_files/aws_environments/aws_environments_all.txt"
with open(aws_env_list, 'r') as aws_envs:
for line in aws_envs.readlines():
line = line.strip() # You can strip it here and reassign it to the same variable
# Now all your previous code with the variable 'line' will work as expected
print(line) # no need to strip again
do_computations(line) # you can pass it to functions without worry

Python readline() on the Mac

New to python and trying to learn the ropes of file i/o.
Working with pulling lines from a large (2 million line) file in this format:
56fr4
4543d
4343d
hirh3
I've been reading that readline() is best because it doesn't pull the whole file into memory. But when I try to read the documentation on it, it seems to be Unix only? And I'm on a Mac.
Can I use readline on the Mac without loading the whole file into memory? What would the syntax be to simply readline number 3 in the file? The examples in the docs are a bit over my head.
Edit
Here is the function to return a code:
def getCode(i):
with open("test.txt") as file:
for index, line in enumerate(f):
if index == i:
code = # what does it equal?
break
return code
You don't need readline:
with open("data.txt") as file:
for line in file:
# do stuff with line
This will read the entire file line-by-line, but not all at once (so you don't need all the memory). If you want to abort reading the file, because you found the line you want, use break to terminate the loop. If you know the index of the line you want, use this:
with open("data.txt") as file:
for index, line in enumerate(file):
if index == 2: # looking for third line (0-based indexes)
# do stuff with this line
break # no need to go on
+1 # SpaceC0wb0y
You could also do:
f = open('filepath')
f.readline() # first line - let it pass
f.readline() # second line - let it pass
third_line = f.readline()
f.close()

Categories

Resources