Reputation: 127
So I'm trying to replace x no. of lines in a text file with a new version of that line. The new line is the same as the old but without the first character '#'. I can't just delete the first character as, of course, strings are immutable. I've created the script below but the changes do not take place. When I print the section in question it is unchanged. I've tried using string.replace() as well but that hasn't worked either. No errors appear so I don't know where I'm going wrong.
import os
import subprocess
x = input('How many unique conformers were identified? ')
with open('file.txt', 'r') as f:
f_contents = f.readlines()
for line in (f_contents[18:(18 + x)]):
newline = str(line[1:(len(line))])
if line[0] == "#":
line = newline
print f_contents[18:(18 + x)]
with open('x.txt', 'w') as f:
f.writelines(f_contents)
Upvotes: 1
Views: 413
Reputation: 25023
Let me introduce the standard library module fileinput
import fileinput
x = input('How many unique conformers were identified? ')
# Python3 input() returns an unevaluated string
x = int(x)
# fileinput objects can be used as context managers
# the inplace=True argument directs to edit the file in place...
with fileinput.input('file.txt', inplace=True) as f:
for line in f:
# decrement the line number to match the list indexing of OP
ln = f.lineno() - 1
# use "<=" and "<" to match slice addressing
if 18 <= ln < (18+x):
# if first character is "#" remove it
if line[0]=='#': line = line[1:]
print(line, end='')
Let me quote from the site I linked above:
Although the script uses print(), no output is produced because fileinput redirects standard output to the file being overwritten.
PS forgot to mention — a backup file is produced before any further processing...
Upvotes: 1
Reputation: 87084
line = newline
simply rebinds the name line
to the value of newline
. It does not modify the value of f_contents
because the value is immutable.
You could try this instead to update the f_contents
list:
offset = 18
x = input('How many unique conformers were identified? ')
with open('file.txt', 'r') as f:
f_contents = f.readlines()
for i in range(offset, offset + x):
if f_contents[i].startswith('#'):
f_contents[i] = f_contents[i][1:]
print f_contents[offset:offset + x]
This slice assignment using a list comprehension will also work:
with open('file.txt', 'r') as f:
f_contents = f.readlines()
f_contents[offset:offset+x] = [line[1:] if line.startswith('#') else line
for line in f_contents[offset:offset+x]]
If you are aiming to write the updated content back out to file then a better way is to iterate over the lines in the file, updating those within the required range of lines, and writing out to a new file.
offset = 18
x = input('How many unique conformers were identified? ')
with open('file.txt', 'r') as infile, open('outfile.txt', 'w') as outfile:
for i, line in enumerate(infile):
if offset <= i < offset+x and line.startswith('#'):
line = line[1:]
outfile.write(line)
Upvotes: 1