Reputation: 3635
another issue I have encountered, I have this code to remove a name from a text file. I am not exactly sure why but sometimes it works fine and does remove the name, but quite often it doesn't, is there a better way of doing this that works 100% of the time? I have changed my filepath and filename as you guys don't need it.
with open(r"MyFilePath\MyFile.txt","r") as file:
participants=[]
for line in file:
participants.append(line)
file.close()
leavingParticipant=input("Enter leaving participant: ")
file=open(r"MyFilePath\MyFile.txt","w")
for participant in participants:
if participant!=leavingParticipant+"\n":
file.write(participant)
file.close()
Upvotes: 1
Views: 1675
Reputation: 107337
Firstly, you don't need to read the lines and append them to a list manually because whenever you open your file the open()
function returns a file object which is an iterator-like object containing all the lines. Or if you want to cache them you can use readlines()
method.
Secondly, you don't need to close the file when you are using with
statement, that's exactly one of its jobs that close the files at the end of the block.
With aforementioned notes in mind, you have some options for doing this which the best one is using a temporary file object for reading and modifying your file at once. Fortunately, python provides us with tempfile
module and you can use NamedTemporaryFile
method in this case. And use shutil.move()
to replace the temp file with the current file.
import tempfile
import shutil
leavingParticipant=input("Enter leaving participant: ")
filename = 'filename'
with open(filename, 'rb') as inp, tempfile.NamedTemporaryFile(mode='wb', delete=False) as out:
for line if inp:
if line != leavingParticipant:
put.write(line)
shutil.move(out.name, filename)
Upvotes: 2
Reputation: 36691
Let's re-write some of your code. First file
is a reserved word, so it is best not to overload it. Second, since you use with
to open the file, you don't need to use .close()
. It does that automatically when the with
clause ends. You don't need to iterate over the list of participants. There are several ways to handle removing an item from a list. Using .remove(item)
is probably the most appropriate here.
with open(r"MyFilePath\MyFile.txt","r") as fp:
participants=[]
for line in fp:
participants.append(line.strip()) #remove the newline character
leavingParticipant = input("Enter leaving participant: ")
with open(r"MyFilePath\MyFile.txt","w") as fp2:
if leavingParticipant in participants:
participant.remove(leavingParticipant)
file.write('\n'.join(participant))
Upvotes: 0
Reputation: 61032
with open(r"MyFilePath\MyFile.txt","r") as file:
participants=[]
for line in file:
participants.append(line)
leavingParticipant=input("Enter leaving participant: ")
with open(r"MyFilePath\MyFile.txt","w") as file:
for participant in participants:
if leavingParticipant != participant.strip():
file.write(participant)
You don't need to manually close files in context managers (The with..as
statements). Instead of trying to play with the whitespace around the information we need, let's just remove it for our comparison.
Upvotes: 2