lines = open(filename).read().splitlines()
Answer from Curt Hagenlocher on Stack Overflowso I have a file that looks something like this:
a
b
c
(blank line)
d
e
f
(blank line)
and I need to create a function that'll print lines until a blank is met, then if I call it again it should print out the next lines until a blank is met again. I tried something like this:
def read(file):
for line in widgetsFile:
while line != "" or line != ' ':
print (widgetsFile.readline())but for some reason that I do not know that kept going endlessly. so how can I achieve what I'm looking to achieve. Thanks i advance.
Also, you should use a for loop OR a while loop, but not both. A for loop with a break statement to stop the loop early is probably best.
The line is actually '\n' when it's blank, not "".
Edit:
You could do something like this:
file 'test' has contents:
a
b
c
d
e
f
g
Use open() to generate lines from the file and while True to keep asking for them
def print_till_blank(gen):
while True:
try:
line = gen.next()
if not line.strip():
break
else:
print line.strip()
except StopIteration:
break
line_gen = open('test')
Then calling the function with your line generator (stops after d):
>>>print_till_blank(line_gen)
a
b
c
d
Calling it again (picks up after blank line)
>>>print_till_blank(line_gen)
e
f
g
python - How to read a file without newlines? - Stack Overflow
file - Python os.read blocks until newline character - Stack Overflow
text - Read Up Until a Point Python - Stack Overflow
How to read from user input until newline is found in Python? - Stack Overflow
lines = open(filename).read().splitlines()
Here's a generator that does what you requested. In this case, using rstrip is sufficient and slightly faster than strip.
lines = (line.rstrip('\n') for line in open(filename))
However, you'll most likely want to use this to get rid of trailing whitespaces too.
lines = (line.rstrip() for line in open(filename))
You can read the whole file and split lines using str.splitlines:
temp = file.read().splitlines()
Or you can strip the newline by hand:
temp = [line[:-1] for line in file]
Note: this last solution only works if the file ends with a newline, otherwise the last line will lose a character.
This assumption is true in most cases (especially for files created by text editors, which often do add an ending newline anyway).
If you want to avoid this you can add a newline at the end of file:
with open(the_file, 'r+') as f:
f.seek(-1, 2) # go at the end of the file
if f.read(1) != '\n':
# add missing newline if not already present
f.write('\n')
f.flush()
f.seek(0)
lines = [line[:-1] for line in f]
Or a simpler alternative is to strip the newline instead:
[line.rstrip('\n') for line in file]
Or even, although pretty unreadable:
[line[:-(line[-1] == '\n') or len(line)+1] for line in file]
Which exploits the fact that the return value of or isn't a boolean, but the object that was evaluated true or false.
The readlines method is actually equivalent to:
def readlines(self):
lines = []
for line in iter(self.readline, ''):
lines.append(line)
return lines
# or equivalently
def readlines(self):
lines = []
while True:
line = self.readline()
if not line:
break
lines.append(line)
return lines
Since readline() keeps the newline also readlines() keeps it.
Note: for symmetry to readlines() the writelines() method does not add ending newlines, so f2.writelines(f.readlines()) produces an exact copy of f in f2.
temp = open(filename,'r').read().split('\n')
Read line by line. Use #main as a flag to start processing. Use #extra as a flag to stop processing.
start = '#main'
end = '#extra'
numbers = []
file_handler = open('read_up_to_a_point.txt')
started = False
for line in file_handler:
if end in line:
started = False
if started:
numbers.append(line.strip())
if start in line:
started = True
file_handler.close()
print numbers
sample output
python read_up_to_a_point.py ['60258960', '33031674', '72302403']
You're pretty close, as you are. You just need to modify your list slice to chop off the last two lines in the file along with the first two. readlines will naturally return a list where each item is one line from the file. However, it will also have the 'newline' character at the end of each string, so you may need to filter that out.
with open("myfile.txt") as myfile:
# Get only numbers
read = myfile.readlines()[2:-2]
# Remove newlines
read = [number.strip() for number in read]
print read
If you are using Python 3.8, you could utilise the walrus operator here
ls = []
while (inp := input("> ")):
ls.append(inp)
print(ls)
Just change it to
while inp:
a.append(inp)
inp = input()
When newline will be entered, inp is an empty string, which is falsy, thus breaking the loop.
I have this code:
with open(inputfile, 'r') as infile:
for line in infile:
if line.startswith(">"):
print line
# keep printing until next ">" encountered; stop at that point
# and move on to next line that starts with ">"...But I don't know how to do that last part...keep printing lines in the file until I hit the next ">", at which point I need it to stop printing, find the next line that starts with ">", then start printing again.
I've searched like every google link for this. It has been asked a lot, but nowhere is there an explanation understand. Usually it's also some variation, such as print from the start until match, but I know how to do that. I need to print from match to match...
I think I can do this with enumerate() a list, and a while loop, but it requires I read the file into memory, which I don't want to do considering the files I need to work on are a few GB each and contain a few million lines, so I don't want to read the entire thing into a list...
The real problem I am having is how to access the "next line" after the line that contains ">"? next(infile) works, but only for the immediate next line. What if I need the next 2 or 3 lines? I tried the following inside the "if line.startswith" part:
line = next(infile)
while not line.startswith(">"):
print line
line = next(infile)But that doesn't work...(not entirely sure why, I assume next() can only take the immediate next line).
Anyone? Is there no default python function (that I can't find) that does this?
files are iterators (unlike lists) so you can just make a second for loop:
with open(inputfile, 'r') as infile:
for line in infile:
if line.startswith(">"):
print line, # comma on the end prevents the double spacing from printing a file line
for line in infile:
print line,
if line.startswith(">"):
break # stop this inner for loop; outer loop picks up on the next line
Edit: I get the feeling I don't understand your problem. Can you show some example data and what you want out?
An easy way to do it would be something like this:
should_print = False
with open(inputfile, 'r') as infile:
for line in infile:
if line.startswith(">"):
# should_print becomes True if was False and becomes False if was True
should_print = not should_print
if should_print:
print(line)
Probably the slickest way that I know (with no error handling, unfortunately, which is why you don't see it too often in production):
>>> lines = list(iter(input, ''))
abc
def
.
g
>>> lines
['abc', 'def', '.', 'g']
This uses the two-parameter call signature for iter, which calls the first argument (input) until it returns the second argument (here '', the empty string).
Your way's not too bad, although it's more often seen under the variation
a = []
while True:
b = input("->")
if not b:
break
a.append(b)
Actually, use of break and continue is one of the rare cases where many people do a one-line if, e.g.
a = []
while True:
b = input("->")
if not b: break
a.append(b)
although this is Officially Frowned Upon(tm).
Your approach is mostly fine. You could write it like this:
a = []
prompt = "-> "
line = input(prompt)
while line:
a.append(int(line))
line = input(prompt)
print(a)
NB: I have not included any error handling.
As to your other question(s):
raw_input()should work similarly in Python 2.7int()-- Coerves the given argument to an integer. It will fail with aTypeErrorif it can't.
For a Python 2.x version just swap input() for raw_input().
Just for the sake of education purposes, you could also write it in a Functional Style like this:
def read_input(prompt):
x = input(prompt)
while x:
yield x
x = input(prompt)
xs = list(map(int, read_input("-> ")))
print(xs)
This is pretty straight forward, you can terminate a loop early with a break statement.
filename = 'somefile.txt'
with open(filename, 'r') as input:
for line in input:
if 'indicator' in line:
break
Using with creates a compound statement that ensures that upon entering and leaving the scope of the with statement __enter__() and __exit__() will be called respectively. For the purpose of file reading this will prevent any dangling filehandles.
The break statement tells the loop to terminate immediately.
Use iter()'s sentinel parameter:
with open('test.txt') as f:
for line in iter(lambda: f.readline().rstrip(), 'SPECIFIC LINE'):
print(line)
output:
file start here..
some data...
Reference: https://docs.python.org/2/library/functions.html#iter