根据特定单词在文本文件(Python)中的位置替换该单词

根据特定单词在文本文件(Python)中的位置替换该单词,python,python-3.x,Python,Python 3.x,我有一个元组列表,每个元组都包含一个要替换的单词,以及它在给定文本文件中的行号和列号位置。我想浏览文本文件,并用字符替换该特定位置的特定单词(例如,[('word1',1,1),('word2',1,9),…])) 换句话说,给定一个特定的单词,它在文本文件中的行号和列号,我正试图查找该单词并将其替换为一个字符,例如: 假设文本文件包含以下内容(假设其位置与此处显示的位置相同,而不是写入的位置相同) 让他兴奋的是,现在自然看到你了。一堆一堆地 成为法庭的希望。朋友们,我要贬低他们。禁止关注 一定

我有一个元组列表,每个元组都包含一个要替换的单词,以及它在给定文本文件中的行号和列号位置。我想浏览文本文件,并用字符替换该特定位置的特定单词(例如,
[('word1',1,1),('word2',1,9),…])

换句话说,给定一个特定的单词,它在文本文件中的行号和列号,我正试图查找该单词并将其替换为一个字符,例如:

假设文本文件包含以下内容(假设其位置与此处显示的位置相同,而不是写入的位置相同)

让他兴奋的是,现在自然看到你了。一堆一堆地 成为法庭的希望。朋友们,我要贬低他们。禁止关注 一定要保密。令人不快,但男人们全神贯注于害羞。假装我 堆叠认真到达公司等。费利西蒂还没有被告知 我承认你有多厉害

假设要替换的单词是
stack
,在文本中的位置是第
3行和第
16列,则将其替换为字符
*

因此,在替换发生后,文本文件现在将包含以下内容:

让他兴奋的是,现在自然看到你了。一堆一堆地 成为法庭的希望。朋友们,我要贬低他们。禁止关注 一定要保密。令人不快,但男人们全神贯注于害羞。假装我 *认真到公司等等。费利西蒂还没有被告知 我承认你有多厉害

我已经考虑过了,但对于大型文本文件来说似乎效率很低。另外,考虑到我已经有了行号和列号,我希望有一种方法可以直接到那个位置执行替换

有人知道用Python实现这一点的方法吗

编辑


使用numpy的
genfromtxt
提出的初始解决方案(很可能)不适合后续讨论,因为需要显示文本文件的每一行且不跳过(例如,空行、以“w”开头的字符串和“/*../”内的字符串)。

尝试以下方法:

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)
结果是:

[ '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.']
请注意,将一组长字符串放入
numpy
数组中,并以某种方式对其进行更改,这有点像黑客,但在插入较长的位置元组循环时,这应该是有效的


编辑:因为@user2357112让我意识到选择文件阅读器不是最合适的(尽管它对所讨论的练习有效),所以我编辑了这个答案,以提供中给出的相同解决方案。

考虑一行:

单词1单词2单词3单词4

如果您有以下更改:

[('word1', 1, 1), ('word2', 1, 9), ... ]
然后按顺序处理它们:

*一个单词2一个单词3一个单词4

您将失败,因为当您用较短的字符串“*”替换“word1”时,您正在更改单词的位置

相反,您必须按行、按列对更改列表进行排序:

changes = sorted(changes, key=lambda t: (t[1], -t[2]))
然后,您可以在迭代文件时处理更改,如@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
打开(“文件”、“r”)作为fp的
:
fpline_text=枚举(fp)
fpline,text=next(fpline\u text)
对于更改中的编辑:
字、行、偏移量=编辑
行-=1#基于0
而fpline
看看这个,它可以帮助您阅读特定的行,但您必须遍历整个文件;您能解释一下
更改此方法吗?@hask.duk该函数正在读取您给出的位置,并将字符串分成两部分:单词前的所有内容和单词后的所有内容(带位置的索引就是为了这个)。比它建立一个新的字符串连接既包括那些部分,又有一个在中间。之后,该元素在numpy数组中被完全替换。如果您感兴趣,请查看此@hask.duk,抱歉使用genfromtxt。我只是想根据你在问题中提供的练习给出一个解决方案。无论如何,我注意到另一个问题引起了很多注意。如果您可能感兴趣,我会跟进这个解决方案(以numpy为基础)。谢谢您再次查看。首先,我应该在我的描述中更明确一些。在实现排序部分时遇到困难:
changes=[('word1',1,1),('word2',1,9),('word2',1,12)]
changes=sorted(changes,key=lambda t:return(t[0],t[1],-t[2])
给我
返回函数外错误
。我做错什么了吗?建议编辑以处理代码错误,并进行修改以匹配预期的描述。我修改了示例。lambda应该只包含一个表达式,而不是返回值:lambda t:(t[1],-t[2])