Index Error When Deleting Lines From A txt File - python

lines = file.readlines()
del lines[68]
This is the code im using to delete the lines, I have already opened the file it works with lots of other stuff. When I run this code it pops up with an index error when Im deleting lines in the middle of the txt file. I ve tried many versions of deleting lines in the txt file but none of them work. Any ideas?

In short
You can add f.seek(0) before f.readlines(), and try your code again.
Long explain
I tried your code and it seems working normally when deleting single element in lines.
Did you use f.readlines() multiple times? In that case, the second time this method will return empty list because the first call already move the cursor to end of file.
To read the file again, you have to use this method f.seek(0) to move the cursor back to the begin of file before calling f.readlines()

How about testing if the txt file has 69 lines at all ?
def delete_line(path, number)
f = opne(path, "r")
lines = f.readlines()
f.close()
if len(lines) - 1 < number:
print("The file %s has not a line number %d" % (path, number))
else:
del lines[number]
return lines
Use it like this:
lines = delete_line("path/to/file/you/want/to/delete/a/line/from.txt", 68)
If your file was long enough, you will have the file minus the specified line saved in lines, else a warning will be printed and the value of lines will be the unmodified file.

Related

"No Keywords Defined" Error in Importing .inp model in Abaqus

I'm having some issues when I import .inp models into Abaqus CAE. I defined this new input file starting from an original input file, and changing the values of some parameters via a Python loop that works fine and produces the new .inp I need.
The fact is that when I try to import the new input files into CAE, it doesn't work and the error NoKeywordsDefinedError appears. The funny fact is that if I copy and paste the content of the new .inp file into the old one, and I import that model, well, it works.
I defined the new .inp using in this way:
inputFile=open('Job-1.inp','r')
outputFile=open('ModifiedInput'+'_RUN'+str(run)+'_LEVEL'+str(r)+'.inp','w')
number_of_lines = 0
for line in inputFile:
line = line.strip("\n")
number_of_lines += 1
if number_of_lines == XXX:
line = line.replace('old','new')
outputFile.write(line)
Maybe I should specify something when I write the lines into the new file?
A few things you could do to improve your script:
Don't strip the new line character, unless you plan on adding it back. When you strip it and then write the text back without the new line character all of your output will end up on a single line.
I am assuming you also want to write out lines that you don't modify, so move your outputFile.write statement outside of the number_of_lines check.
Close your file at the end of the script to make sure the written contents are flushed.
inputFile=open('Job-1.inp','r')
outputFile=open('ModifiedInput'+'_RUN'+str(run)+'_LEVEL'+str(r)+'.inp','w')
number_of_lines = 0
for line in inputFile:
#line = line.strip("\n")
number_of_lines += 1
if number_of_lines == XXX:
line = line.replace('old','new')
outputFile.write(line)
inputFile.close()
outputFile.close()

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.

how to save changes after modifying content in file using Python

I want to insert a line into file "original.txt" (the file contains about 200 lines). the line neds to be inserted two lines after a string is found in one of the existing lines. This is my code, I am using a couple of print options that show me that the line is being added to the list, in the spot I need, but the file "original.txt" is not being edited
with open("original.txt", "r+") as file:
lines = file.readlines() # makes file into a list of lines
print(lines) #test
for number, item in enumerate(lines):
if testStr in item:
i = number +2
print(i) #test
lines.insert(i, newLine)
print(lines) #test
break
file.close()
I am turning the lines in the text into a list, then I enumerate the lines as I look for the string, assigning the value of the line to i and adding 2 so that the new line is inserted two lines after, the print() fiction shows the line was added in the correct spot, but the text "original.txt" is not modified
You seem to misunderstand what your code is doing. Lets go line by line
with open("original.txt", "r+") as file: # open a file for reading
lines = file.readlines() # read the contents into a list of lines
print(lines) # print the whole file
for number, item in enumerate(lines): # iterate over lines
if testStr in item:
i = number +2
print(i) #test
lines.insert(i, newLine) # insert lines into the list
print(lines) #test
break # get out of the look
file.close() # not needed, with statement takes care of closing
You are not modifying the file. You read the file into a list of strings and modify the list. To modify the actual file you need to open it for writing and write the list back into it. Something like this at the end of the code might work
with open("modified.txt", "w") as f:
for line in lines: f.write(line)
You never modified the original text. Your codes reads the lines into local memory, one at a time. When you identify your trigger, you count two lines, and then insert the undefined value newLine into your local copy. At no point in your code did you modify the original file.
One way is to close the file and then rewrite it from your final value of lines. Do not modify the file while you're reading it -- it's good that you read it all in and then start processing.
Another way is to write to a new file as you go, then use a system command to replace the original file with your new version.

Read line from file, process it, then remove it

I have a 22mb text file containing a list of numbers (1 number per line). I am trying to have python read the number, process the number and write the result in another file. All of this works but if I have to stop the program it starts all over from the beginning. I tried to use a mysql database at first but it was way too slow. I am getting about 4 times the number being processed this way. I would like to be able to delete the line after the number was processed.
with open('list.txt', 'r') as file:
for line in file:
filename = line.rstrip('\n') + ".txt"
if os.path.isfile(filename):
print "File", filename, "exists, skipping!"
else:
#process number and write file
#(need code to delete current line here)
As you can see every time it is restarted it has to search the hard drive for the file name to make sure it gets to the place it left off. With 1.5 million numbers this can take a while. I found an example with truncate but it did not work.
Are there any commands similar to array_shift (PHP) for python that will work with text files.
I would use a marker file to keep the number of the last line processed instead of rewriting the input file:
start_from = 0
try:
with open('last_line.txt', 'r') as llf: start_from = int(llf.read())
except:
pass
with open('list.txt', 'r') as file:
for i, line in enumerate(file):
if i < start_from: continue
filename = line.rstrip('\n') + ".txt"
if os.path.isfile(filename):
print "File", filename, "exists, skipping!"
else:
pass
with open('last_line.txt', 'w') as outfile: outfile.write(str(i))
This code first checks for the file last_line.txt and tries to read a number from it. The number is the number of line which was processed in during the previous attempt. Then it simply skips the required number of lines.
I use Redis for stuff like that. Install redis and then pyredis and you can have a persistent set in memory. Then you can do:
r = redis.StrictRedis('localhost')
with open('list.txt', 'r') as file:
for line in file:
if r.sismember('done', line):
continue
else:
#process number and write file
r.sadd('done', line)
if you don't want to install Redis you can also use the shelve module, making sure that you open it with the writeback=False option. I really recommend Redis though, it makes things like this so much easier.
Reading the data file should not be a bottleneck. The following code read a 36 MB, 697997 line text file in about 0,2 seconds on my machine:
import time
start = time.clock()
with open('procmail.log', 'r') as f:
lines = f.readlines()
end = time.clock()
print 'Readlines time:', end-start
Because it produced the following result:
Readlines time: 0.1953125
Note that this code produces a list of lines in one go.
To know where you've been, just write the number of lines you've processed to a file. Then if you want to try again, read all the lines and skip the ones you've already done:
import os
# Raad the data file
with open('list.txt', 'r') as f:
lines = f.readlines()
skip = 0
try:
# Did we try earlier? if so, skip what has already been processed
with open('lineno.txt', 'r') as lf:
skip = int(lf.read()) # this should only be one number.
del lines[:skip] # Remove already processed lines from the list.
except:
pass
with open('lineno.txt', 'w+') as lf:
for n, line in enumerate(lines):
# Do your processing here.
lf.seek(0) # go to beginning of lf
lf.write(str(n+skip)+'\n') # write the line number
lf.flush()
os.fsync() # flush and fsync make sure the lf file is written.

Python: Write to next empty line

I'm trying to write the output of something that is being done over three big iterations and each time I'm opening and closing the outfile. Counters get reset and things like this after the iterations and I'm a massive newb and would struggle to work around this with the shoddy code I've written. So even if it's slower I'd like change the way it is being output.
Currently for the output it's just rewriting over the first line so I have only the output of the last run of the program. (tau, output are variables given values in the iterations above in the code)
with open(fileName + '.autocorrelate', "w") as outfile:
outfile.writelines('{0} {1}{2}'.format(tau, output, '\n'))
I was wondering if there are any quick ways to get python to check for the first empty line when it opens a file and write the new line there?
Open with "a" instead of "w" will write at the end of the file. That's the way to not overwrite.
If you open your file in append mode : "a" instead of "w", you will be able to write a new line at the end of your file.
You do do something like that to keep a reference (line number) to every empty line in a file
# Get file contents
fd = open(file)
contents = fd.readlines()
fd.close()
empty_line = []
i = 0
# find empty line
for line in contents:
if line == "":
empty_line.append(i)
i+=1

Categories

Resources