Reputation: 53
I have this text which i will share a part from,
ROMEO
But, soft! what light through yonder window breaks? It is the east, and Juliet is the sun.
JULIET
Ay me!
ROMEO
She speaks: O, speak again, bright angel! for thou art.
JULIET
O Romeo, Romeo! wherefore art thou Romeo? Deny thy father and refuse thy name;
ROMEO
Shall I hear more, or shall I speak at this?.
I want to write a loop that looks for the name in the line and saves the contents after it to a specific file, in this case if "ROMEO" is the word found every line after it will be saved to "Romeo.txt" until the word "JULIET" is found then all content is saved to "Juliet.txt". I tried coding it myself with an amalgamation of loops and if statements but it got me to nowhere. handle = open("romeo-full.txt") skipper = "ROMEO"
handle = open("romeo-full.txt")
skipper = "ROMEO"
for line in handle:
line = line.strip()
while skipper == "ROMEO":
print(line) #This would be the write to file code
if line.startswith("ROMEO"):
skipper = "JULIET"
break
else:
continue
while skipper == "JULIET":
print(line) #This would be the write to file code
if line.startswith("ROMEO"):
skipper = "ROMEO"
break
else:
continue
The output is basically "ROMEO" lines looping, which i understood it's coming from the while loop going through the first line forever, but i couldn't figure a way out closer to what i want than this.
Upvotes: 1
Views: 61
Reputation: 19414
One way to avoid the duplicated code will be to use the headers in the main file as "choosers" for the what file to write to. Something like:
with open("romeo-full.txt") as handle, \
open("romeo.txt", 'w') as r_f, \
open("juliet.txt", 'w') as j_f:
file_chooser = {"ROMEO": r_f,
"JULIET": j_f}
for line in handle:
try:
cur_file = file_chooser[line.strip()]
except KeyError:
cur_file.write(line)
The purpose of the try/except
block is to change the cur_file
only when we encounter one of the headings (and then skip it).
One way to avoid that is to use dict's get
method with cur_file
as the default (so it changes only on headers):
with open("romeo-full.txt") as handle, \
open("romeo.txt", 'w') as r_f, \
open("juliet.txt", 'w') as j_f:
file_chooser = {"ROMEO": r_f,
"JULIET": j_f}
cur_file = r_f
for line in handle:
cur_file = file_chooser.get(line.strip(), cur_file)
cur_file.write(line)
The downside here is that the headers will also be written each time to the files.
Upvotes: 1
Reputation: 3648
You can write to multiple files like so:
with open('example1.txt', 'w') as file_1 \
, open('example2.txt', 'w') as file_2 \
, open('example3.txt', 'w') as file_3 \
, open("romeo-full.txt", 'r') as handle:
for line in handle:
if condition_1:
file_1.write(line)
elif condition_2:
file_2.write(line)
elif condition_3:
file_3.write(line)
The reason you should always use with
instead of open
and close
is because if for some reason you don't close (like the program crashing or you forgetting to add it), the file will not be closed, taking up space. I've seen it happen that files that are frequently opened and not closed cause servers to crash!
Upvotes: 0