I have a list of tuples, each on contains a word-to-be-replaced, its line and column number positions from a given text file. I want to go through the text file and repl
Consider a single line:
word1 a word2 a word3 a word4
If you have these changes:
[('word1', 1, 1), ('word2', 1, 9), ... ]
And you process them in order:
* a word2 a word3 a word4
You will fail, because you are changing the positions of the words when you replace 'word1' with '*', a shorter string.
Instead, you will have to sort the list of changes by line, reversed by column:
changes = sorted(changes, key=lambda t: (t[1], -t[2]))
You can then process the changes as you iterate through the file, shown in the link referenced by @JRajan:
with open("file", "r") as fp:
fpline_text = enumerate(fp)
fpline,text = next(fpline_text)
for edit in changes:
word,line,offset = edit
line -=1 # 0 based
while fpline < line:
print(text)
fpline,text = next(fpline_text)
offset -= 1 # 0-based
cand = text[offset:offset+len(word)]
if cand != word:
print("OOPS! Word '{}' not found at ({}, {})".format(*edit))
else:
text = text[0:offset]+'*'+text[offset+len(word):]
# Rest of file
try:
while True:
print(text)
fpline,text = next(fpline_text)
except StopIteration:
pass
Try a recipe like this:
import numpy as np
import os
def changethis(pos):
# Notice file is in global scope
appex = file[pos[1]-1][:pos[2]] + '*' + file[pos[1]-1][pos[2]+len(pos[0]):]
file[pos[1]-1] = appex
pos = ('stack', 3, 16)
file = np.array([i for i in open('in.txt','r')]) #BEFORE EDIT: np.genfromtxt('in.txt',dtype='str',delimiter=os.linesep)
changethis(pos)
print(file)
The result is this:
[ 'Excited him now natural saw passage offices you minuter. At by stack being court hopes. Farther'
'so friends am to detract. Forbade concern do private be. Offending residence but men engrossed'
'shy. Pretend am * earnest arrived company so on. Felicity informed yet had to is admitted'
'strictly how stack you.']
Notice this is a bit of an hack to put a bunch of long strings into a numpy
array, and somehow change them, but it should be efficient when inserting in a longer loop for position tuples.
EDIT: As @user2357112 made me realize the choice for file reader was not the most appropriate (although it worked for the exercise in question), so I've edited this answer to provide the same solution given in the follow up question.