Python, adding a file into another file - python

I have to define a function: save_file(filename, new_list) which takes a file name and a new list and writes that list to the file in the correct format.
So, for example,
save_file(’file.txt’, load_file(’file.txt’))
(load_file is a predefined function which opens and reads the file)
should overwrite the new list with exactly the same content.
I have no clue how to go about this, any ideas?
The load_file function seems to work but can't seem to get the save_file function working.
This is what I have so far:
I have this so far:
def load_file(filename):
f = open(filename, 'Ur')
for line in f:
print line
f.close()
def save_file(filename, new_list):
with open(new_list, 'Ur') as f1:
with open(filename, 'w') as f2:
f2.write(f1.read())

Since new_list is clearly a list of lines, not a filename, you don't need all the stuff with opening and reading it. And you also can't do saving in a single write.
But you can do it almost that simply.
You didn't specify whether the lines in new_list still have their newlines. Let's first assume they do. So, all you have to do is:
def save_file(filename, new_list):
with open(filename, 'w') as f:
f.write(''.join(new_list))
… or …:
def save_file(filename, new_list):
with open(filename, 'w') as f:
f.writelines(new_list)
But your teacher may be expecting something like this:
def save_file(filename, new_list):
with open(filename, 'w') as f:
for line in new_list:
f.write(line)
What if the newlines were stripped off, so we have to add them back? Then things are a bit more complicated the first two ways, but still very easy the third way:
def save_file(filename, new_list):
with open(filename, 'w') as f:
f.write('\n'.join(new_list) + '\n')
def save_file(filename, new_list):
with open(filename, 'w') as f:
f.writelines(line + '\n' for line in new_list)
def save_file(filename, new_list):
with open(filename, 'w') as f:
for line in new_list:
f.write(line + '\n')
Meanwhile, you have not gotten load_file to work. It's supposed to return a list of lines, but it doesn't return anything (or, rather, it returns None). printing something just prints it out for the user to see, it doesn't store anything for later use.
You want something like this:
def load_file(filename):
lines = []
with open(filename, 'Ur') as f:
for line in f:
lines.append(line)
return lines
However, there's a much simpler way to write this. If you can do for line in f:, then f is some kind of iterable. It's almost the same thing as a list—and if you want to make it into an actual list, that's trivial:
def load_file(filename):
with open(filename, 'Ur') as f:
return list(f)

def save_file(filename, new_list):
with open(new_list, 'r') as a:
with open(filename, 'w') as b:
b.write(a.read())
Just a small adjustment to SaltChicken's answer.

Use print >> to make it simply :
>>> with open('/src/file', 'r') as f1, open('/dst/file', 'w') as f2:
... print >> f2, f1.read()
Inspired from What does this code mean: "print >> sys.stderr".

Related

Saving text file in a for loop

I'm trying to loop through a file, strip the sentences into individual lines, and then export that data.
filename = '00000BF8_ar.txt'
with open(filename, mode="r") as outfile:
str_output = outfile.readlines()
str_output = ''.join(str_output)
sentenceSplit = filter(None, str_output.split("."))
for s in sentenceSplit:
print(s.strip() + ".")
#output += s
myfile = open(filename, 'w')
myfile.writelines(s)
myfile.close()
Unfortunately, it looks like the loop only goes through a few lines and saves them. So the whole file isn't looped through and saved. Any help on how I can fix that?
Here is the code I hope this is what you want to achieve,
filename = '00000BF8_ar.txt'
with open(filename, mode="r") as outfile:
str_output = outfile.readlines()
str_output = ''.join(str_output)
sentenceSplit = filter(None, str_output.split("."))
l=[]
for s in sentenceSplit:
l.append(s.strip() + ".")
myfile = open(filename, 'w')
myfile.write('\n'.join(l))
myfile.close()
Each time you re-open the file with the 'w' option, you basically erase its content.
Try modifying your code like this:
filename = '00000BF8_ar.txt'
with open(filename, "r") as infile:
str_output = infile.readlines()
str_output = ''.join(str_output)
sentenceSplit = filter(None, str_output.split("."))
with open(filename, "w") as outfile:
for s in sentenceSplit:
print(s.strip() + ".")
#output += s
s.writelines(s)
Another way to achieve the same thing would have been to open a new file using open(filename_new, 'a') which open a file for appending, but as a rule of thumb try not to open/close files inside a loop.
open(filename, 'w') will overwrite the file every time it starts. My guess is that what's currently happening is that only the last element in sentenceSplit is showing up in myfile.
The simple "solution" is to use append instead of write:
open(filename, 'a')
which will simply start writing at the end of the file, without deleting the rest of it.
However, as #chepner's comment states, why are you reopening the file at all? I would recommend changing your code to this:
with open(filename, mode="r") as outfile:
str_output = outfile.readlines()
str_output = ''.join(str_output)
sentenceSplit = filter(None, str_output.split("."))
with open(filename, mode='w') as myfile:
for s in sentenceSplit:
print(s.strip() + ".")
myfile.writelines(s)
This way, instead of opening it many times, and overwriting it every time, you're only opening it once and just writing to it continuously.

Python script that will go through folders and replace content in them [duplicate]

Currently I'm using this:
f = open(filename, 'r+')
text = f.read()
text = re.sub('foobar', 'bar', text)
f.seek(0)
f.write(text)
f.close()
But the problem is that the old file is larger than the new file. So I end up with a new file that has a part of the old file on the end of it.
If you don't want to close and reopen the file, to avoid race conditions, you could truncate it:
f = open(filename, 'r+')
text = f.read()
text = re.sub('foobar', 'bar', text)
f.seek(0)
f.write(text)
f.truncate()
f.close()
The functionality will likely also be cleaner and safer using open as a context manager, which will close the file handler, even if an error occurs!
with open(filename, 'r+') as f:
text = f.read()
text = re.sub('foobar', 'bar', text)
f.seek(0)
f.write(text)
f.truncate()
The fileinput module has an inplace mode for writing changes to the file you are processing without using temporary files etc. The module nicely encapsulates the common operation of looping over the lines in a list of files, via an object which transparently keeps track of the file name, line number etc if you should want to inspect them inside the loop.
from fileinput import FileInput
for line in FileInput("file", inplace=1):
line = line.replace("foobar", "bar")
print(line)
Probably it would be easier and neater to close the file after text = re.sub('foobar', 'bar', text), re-open it for writing (thus clearing old contents), and write your updated text to it.
I find it easier to remember to just read it and then write it.
For example:
with open('file') as f:
data = f.read()
with open('file', 'w') as f:
f.write('hello')
To anyone who wants to read and overwrite by line, refer to this answer.
https://stackoverflow.com/a/71285415/11442980
filename = input("Enter filename: ")
with open(filename, 'r+') as file:
lines = file.readlines()
file.seek(0)
for line in lines:
value = int(line)
file.write(str(value + 1))
file.truncate()
Honestly you can take a look at this class that I built which does basic file operations. The write method overwrites and append keeps old data.
class IO:
def read(self, filename):
toRead = open(filename, "rb")
out = toRead.read()
toRead.close()
return out
def write(self, filename, data):
toWrite = open(filename, "wb")
out = toWrite.write(data)
toWrite.close()
def append(self, filename, data):
append = self.read(filename)
self.write(filename, append+data)
Try writing it in a new file..
f = open(filename, 'r+')
f2= open(filename2,'a+')
text = f.read()
text = re.sub('foobar', 'bar', text)
f.seek(0)
f.close()
f2.write(text)
fw.close()

How to delete a tuple from a file in python

imp,2,6,7
ads,4,5,6
sfd,2,5,8
I have a text file that looks like this
I want to delete the line that has imp in it.
All the other methods I have seen to delete lines from files only work for single strings
Following this question link, you can try this:
fn = 'Test.txt'
f = open(fn)
output = []
for line in f:
if not "imp" in line:
output.append(line)
f.close()
f = open(fn, 'w')
f.writelines(output)
f.close()
Result:
ads,4,5,6
sfd,2,5,8

How to Open a file through python

I am very new to programming and the python language.
I know how to open a file in python, but the question is how can I open the file as a parameter of a function?
example:
function(parameter)
Here is how I have written out the code:
def function(file):
with open('file.txt', 'r') as f:
contents = f.readlines()
lines = []
for line in f:
lines.append(line)
print(contents)
You can easily pass the file object.
with open('file.txt', 'r') as f: #open the file
contents = function(f) #put the lines to a variable.
and in your function, return the list of lines
def function(file):
lines = []
for line in f:
lines.append(line)
return lines
Another trick, python file objects actually have a method to read the lines of the file. Like this:
with open('file.txt', 'r') as f: #open the file
contents = f.readlines() #put the lines to a variable (list).
With the second method, readlines is like your function. You don't have to call it again.
Update
Here is how you should write your code:
First method:
def function(file):
lines = []
for line in f:
lines.append(line)
return lines
with open('file.txt', 'r') as f: #open the file
contents = function(f) #put the lines to a variable (list).
print(contents)
Second one:
with open('file.txt', 'r') as f: #open the file
contents = f.readlines() #put the lines to a variable (list).
print(contents)
Hope this helps!
Python allows to put multiple open() statements in a single with. You comma-separate them. Your code would then be:
def filter(txt, oldfile, newfile):
'''\
Read a list of names from a file line by line into an output file.
If a line begins with a particular name, insert a string of text
after the name before appending the line to the output file.
'''
with open(newfile, 'w') as outfile, open(oldfile, 'r', encoding='utf-8') as infile:
for line in infile:
if line.startswith(txt):
line = line[0:len(txt)] + ' - Truly a great person!\n'
outfile.write(line)
# input the name you want to check against
text = input('Please enter the name of a great person: ')
letsgo = filter(text,'Spanish', 'Spanish2')
And no, you don't gain anything by putting an explicit return at the end of your function. You can use return to exit early, but you had it at the end, and the function will exit without it. (Of course with functions that return a value, you use the return to specify the value to return.)
def fun(file):
contents = None
with open(file, 'r') as fp:
contents = fp.readlines()
## if you want to eliminate all blank lines uncomment the next line
#contents = [line for line in ''.join(contents).splitlines() if line]
return contents
print fun('test_file.txt')
or you can even modify this, such a way it takes file object as a function arguement as well
Here's a much simpler way of opening a file without defining your own function in Python 3.4:
var=open("A_blank_text_document_you_created","type_of_file")
var.write("what you want to write")
print (var.read()) #this outputs the file contents
var.close() #closing the file
Here are the types of files:
"r": just to read a file
"w": just to write a file
"r+": a special type which allows both reading and writing of the file
For more information see this cheatsheet.
def main():
file=open("chirag.txt","r")
for n in file:
print (n.strip("t"))
file.close()
if __name__== "__main__":
main()
the other method is
with open("chirag.txt","r") as f:
for n in f:
print(n)

How to add a copy of each line in a txt (containing two parts separated by a particular symbol) with the order of the two parts inverted?

I have txt with a number of lines (x#y). Each file has two parts (x, y) separated by a particular symbol (#). How would a python script that reads each line in a txt and adds a new line under each existing line, where the order of the two parts (x#y) is inverted (y#x).
What I'm trying to do presented as input/output:
INPUT:
x1#y1
x2#y2
x3#y3
OUTPUT:
x1#y1
y1#x1
x2#y2
y2#x2
x3#y3
y3#x3
How can this be done with python?
Here's one way:
infilename = 'in.dat'
outfilename = 'out.dat'
sep = '#'
with open(infilename) as infile, open(outfilename,'w') as outfile:
for line in infile:
split = line.strip().partition(sep)
outfile.write(line)
outfile.write(''.join(reversed(split)) + '\n')
and then
~/coding$ cat in.dat
x1#y1
x2#y2
x3#y3
~/coding$ python inverter.py
~/coding$ cat out.dat
x1#y1
y1#x1
x2#y2
y2#x2
x3#y3
y3#x3
Assumes the name of your file is bar.txt, and that you want to write it back to bar.txt. It also does no error checking nor cares about memory usage.
if __name__ == "__main__":
myfile = open("bar.txt", "rb")
lines = myfile.readlines()
myfile.close()
myfile = open("bar.txt", "wb")
for l in lines:
ls = l.strip()
myfile.write(ls + "\n")
lsplit = ls.split("#")
myfile.write(lsplit[1] + "#" + lsplit[0] + "\n")
myfile.close()
There are cleaner ways to do this, but you could use something like:
f = open('my_file.txt', 'r')
lines = f.readlines()
f.close()
outfile = open('my_file2.txt', 'w')
# write each line, followed by flipped line
for line in lines:
outfile.write('%s\n' % line)
parts = line.split('#')
outfile.write('%s#%s\n' % [parts[1], parts[0]])
outfile.close()
You can use open and read function to read your file and than use this function,
>>> st = "x1#y1"
>>> def myfunc(string):
... mylist = re.split(r'(#)',string)
... mylist.reverse()
... print "".join(mylist), string
...
>>> myfunc(st)
y1#x1 x1#y1
and than use write to write the strings into your new file.
def swap(delimiter="#", input="input.txt", ouput="output.txt"):
with open(input, "r") as input_file, open(ouput, "w") as output_file:
for line in input_file:
line = line.strip()
output_line = delimiter.join(reversed(line.split(delimiter)))
output_file.write(line+"\n")
output_file.write(output_line+"\n")
swap()
Riffing on #DSM:
with open(infilename) as infile, open(outfilename, 'w') as outfile:
lines = [line.rstrip() for line in infile]
outfile.write("\n".join("%s\n%s%s%s" (line, y, sep, x)
for line in lines
for x, y in line.split(sep)) + "\n")
lines could also be a generator statement instead of a list comprehension:
lines = (line.rstrip() for line in infile)
Later: I did not realize until now that OP wanted the original line followed by the reversed line. Adjusted accordingly.

Categories