在Python中替换来自不同数据集的字符串中的多个单词

在Python中替换来自不同数据集的字符串中的多个单词,python,string,random,Python,String,Random,本质上,我有一个python脚本,它加载许多文件,每个文件都包含一个列表,这些列表用于生成字符串。例如:“刚刚在$location%中看到$film%,我强烈推荐!”我需要用各自导入列表数组的随机元素替换$film%和$location%占位符 我对Python非常陌生,但很容易就掌握了大部分内容,但很明显在Python中字符串是不可变的,因此处理此类任务与我使用的其他语言不同 这是目前的代码,我已经尝试添加了一个while循环,但它仍然只会替换一个可替换单词的第一个实例,剩下的就不做了 #!/

本质上,我有一个python脚本,它加载许多文件,每个文件都包含一个列表,这些列表用于生成字符串。例如:“刚刚在$location%中看到$film%,我强烈推荐!”我需要用各自导入列表数组的随机元素替换$film%和$location%占位符

我对Python非常陌生,但很容易就掌握了大部分内容,但很明显在Python中字符串是不可变的,因此处理此类任务与我使用的其他语言不同

这是目前的代码,我已经尝试添加了一个while循环,但它仍然只会替换一个可替换单词的第一个实例,剩下的就不做了

#!/usr/bin/python
import random

def replaceWord(string):
   #Find Variable Type
   if "url" in string:
       varType = "url"
   elif "film" in string:
       varType = "film"
   elif "food" in string:
       varType = "food"
   elif "location" in string:
       varType = "location"
    elif "tvshow" in string:
        varType = "tvshow"

   #LoadVariableFile
   fileToOpen = "/prototype/default_" + varType + "s.txt"
   var_file = open(fileToOpen, "r")
   var_array = var_file.read().split('\n')

   #Get number of possible variables
   numberOfVariables = len(var_array)

   #ChooseRandomElement
   randomElement = random.randrange(0,numberOfVariables)

   #ReplaceWord
   oldValue = "$" + varType + "%"
   newString = string.replace(oldValue, var_array[randomElement], 1)

   return newString

testString = "Just been to see $film% in $location%, I'd highly recommend it!"
Test = replaceWord(testString)
这将提供以下输出:刚刚在$location%中看到哈利波特,我强烈推荐它


我尝试过使用while循环,计算字符串中要替换的单词数等。但是它仍然只更改第一个单词。它还需要能够替换同一字符串中相同“变量”类型的多个实例,因此,如果一个字符串中出现两个$film%,则应使用加载文件中的随机元素替换这两个实例。

关于代码的几点:

  • 您可以将randrange替换为 要从数组中选择项
  • 您可以迭代您的类型并进行替换,而无需 指定一个限制(第三个参数),然后将其指定给同一个对象,以便保留所有替换项
  • readlines()执行打开所需的操作,从文件中读取,并将行存储为数组
  • 完成所有可能的替换后返回新字符串
大概是这样的:

#!/usr/bin/python
import random

def replaceWord(string):
   #Find Variable Type
   types = ("url", "film", "food", "location", "tvshow")
   for t in types:
      if "$" + t + "%" in string:
        var_array = []
        #LoadVariableFile
        fileToOpen = "/prototype/default_" + varType + "s.txt"
        with open(fname) as f:
           var_array = f.readlines()

        tag = "$" + t + "%"
        while tag in string:
            choice = random.choice(var_array)
            string = string.replace(tag, choice, 1)
            var_array.remove(choice)

   return string

testString = "Just been to see $film% in $location%, I'd highly recommend it!"
new = replaceWord(testString)
print(new)

您分配的
varType
将仅在一个
if else
序列中设置,然后解释器将转到外部。你必须在它上面运行并执行操作。一种方法是设置要更改句子的哪一部分的标志。它会是这样的:

url_to_change = False
film_to_change = False
if "url" in string:
    url_to_change = True
elif "film" in string:
    film_to_change = True

if url_to_change:
    change_url()
if film_to_change:
    change_film()
如果要更改所有发生的情况,可以使用
foreach
循环。只需在交换单词的部分执行以下操作:

for word in sentence:
    if word == 'url':
        change_word()
说到这里,我建议引入两个改进。推动转换为单独的功能。管理代码会更容易。 例如,将项目从文件中随机获取的函数可以是

def load_variable_file(file_name)
    fileToOpen = "/prototype/default_" + file_name + "s.txt"
    var_file = open(fileToOpen, "r")
    var_array = var_file.read().split('\n')
    var_file.clos()
    return var_array
而不是

if "url" in string:
    varType = "url"
你可以做:

def change_url(sentence):
    var_array = load_variable_file(url)
    numberOfVariables = len(var_array)
    randomElement = random.randrange(0,numberOfVariables)
    oldValue = "$" + varType + "%"
    return sentence.replace(oldValue, var_array[randomElement], 1)

if "url" in sentence:
    setnence = change_url(sentence)

等等。您可以将我放入change_url()中的部分内容推送到一个单独的函数中,因为所有这些函数都会使用它(就像从文件加载数据一样)。我故意不改变一切,希望你明白我的意思。正如您看到的,使用名称清晰的函数,您可以编写更少的代码,将其拆分为逻辑的、可重用的部分,无需对代码进行注释。

下面的程序可能更接近您要实现的目标。请注意,包含的文档有助于解释正在发生的事情。模板与您的略有不同,但提供了自定义选项

#! /usr/bin/env python3
import random


PATH_TEMPLATE = './prototype/default_{}s.txt'


def main():
    """Demonstrate the StringReplacer class with a test sting."""
    replacer = StringReplacer(PATH_TEMPLATE)
    text = "Just been to see {film} in {location}, I'd highly recommend it!"
    result = replacer.process(text)
    print(result)


class StringReplacer:

    """StringReplacer(path_template) -> StringReplacer instance"""

    def __init__(self, path_template):
        """Initialize the instance attribute of the class."""
        self.path_template = path_template
        self.cache = {}

    def process(self, text):
        """Automatically discover text keys and replace them at random."""
        keys = self.load_keys(text)
        result = self.replace_keys(text, keys)
        return result

    def load_keys(self, text):
        """Discover what replacements can be made in a string."""
        keys = {}
        while True:
            try:
                text.format(**keys)
            except KeyError as error:
                key = error.args[0]
                self.load_to_cache(key)
                keys[key] = ''
            else:
                return keys

    def load_to_cache(self, key):
        """Warm up the cache as needed in preparation for replacements."""
        if key not in self.cache:
            with open(self.path_template.format(key)) as file:
                unique = set(filter(None, map(str.strip, file)))
            self.cache[key] = tuple(unique)

    def replace_keys(self, text, keys):
        """Build a dictionary of random replacements and run formatting."""
        for key in keys:
            keys[key] = random.choice(self.cache[key])
        new_string = text.format(**keys)
        return new_string


if __name__ == '__main__':
    main()

这非常有效,唯一的缺点是返回的字符串现在似乎在多行上,但是删除换行符非常容易!很高兴听到,请向上投票/接受答案,因为它解决了您的问题:刚刚注意到一个问题,当包含多个相同类型的实例时,例如两部电影,它将为两部电影分配相同的随机选择,而不是唯一的随机选择values@SamB只是换了它来处理这个案子,你只需要一个接一个的更换,注意不要重复一个项目。注意到一个奇怪的问题,例如,如果有三种不同的类型,但其中两种是相同的,则相同的两种都不会被替换。i、 e.“使用$name%和%name$转到$location%只会替换位置部分,如果只使用字符串,但使用文件中的行似乎是问题的原因。这实际上非常适合我的需要,谢谢!如果你发现它有用,你可以考虑对答案进行投票。