用多个字典值替换字符串中的单词?

Posted

技术标签:

【中文标题】用多个字典值替换字符串中的单词?【英文标题】:Replacing words in a string with multiple dictionary values? 【发布时间】:2019-01-29 03:34:24 【问题描述】:

我有一个句子模板字符串和一个所需替换词的字典:

template = "Who was <Name>'s <Job> in <Month>?"
dictionary = Name: [John,Peter,Paul],
              Job:  [Designer,Carpenter,Lawyer],
              Month:[October,July,March]
             

我想生成一个句子列表,每个替换组合一个:

question_list=["Who was <John>'s <Lawyer> in <October>?",
               "Who was <Peter>'s <Lawyer> in <October>?",
               "Who was <John>'s <Designer> in <July>?",
               ... ]

列表的顺序无所谓,不需要去掉括号''。

目前我有:

def replace(template, dictionary):
    question_list = []
    for word in template:
        for key in dictionary:
            if word == key:
                new_string = template.replace(word, dictionary[key])
                question_list.append(new_string)
            return question_list

这会将question_list 作为一个空列表返回。

我很确定我的主要问题是我不知道如何/没有第三个for loop 来访问字典值列表中的每个项目,但我没有足够的经验知道有多糟糕我搞砸了。我该如何解决这个问题?

【问题讨论】:

阅读ericlippert.com/2014/03/05/how-to-debug-small-programs 了解如何调试代码的一些技巧。 “单词”永远不会匹配,因为包含尖括号,因此没有任何内容附加到列表中 你也应该看看python给你的string operations。这些可以帮助您编写更少的代码。 你能改变你的字符串吗? 【参考方案1】:

您可以使用re.subitertools.product

import re, itertools
template = "Who was <Name>'s <Job> in <Month>?"
dictionary = 'Name': ['John', 'Peter', 'Paul'], 'Job': ['Designer', 'Carpenter', 'Lawyer'], 'Month': ['October', 'July', 'March']
headers = re.findall('(?<=\<)\w+(?=\>)', template)
full_vals = itertools.product(*[dictionary[i] for i in headers])
final_results = [re.sub('\<\w+\>', lambda x:''+x.group()[1:-1]+'', template).format(**dict(zip(headers, i))) for i in full_vals]

输出:

["Who was John's Designer in October?", "Who was John's Designer in July?", "Who was John's Designer in March?", "Who was John's Carpenter in October?", "Who was John's Carpenter in July?", "Who was John's Carpenter in March?", "Who was John's Lawyer in October?", "Who was John's Lawyer in July?", "Who was John's Lawyer in March?", "Who was Peter's Designer in October?", "Who was Peter's Designer in July?", "Who was Peter's Designer in March?", "Who was Peter's Carpenter in October?", "Who was Peter's Carpenter in July?", "Who was Peter's Carpenter in March?", "Who was Peter's Lawyer in October?", "Who was Peter's Lawyer in July?", "Who was Peter's Lawyer in March?", "Who was Paul's Designer in October?", "Who was Paul's Designer in July?", "Who was Paul's Designer in March?", "Who was Paul's Carpenter in October?", "Who was Paul's Carpenter in July?", "Who was Paul's Carpenter in March?", "Who was Paul's Lawyer in October?", "Who was Paul's Lawyer in July?", "Who was Paul's Lawyer in March?"]

【讨论】:

【参考方案2】:

如果这是 3.6 并且您可以将字符串更改为 f-stringproduct 您不需要正则表达式来处理它:

dictionary = 'Name':['John','Peter','Paul'],'Job':['Designer','Carpenter','Lawyer'],'Month':['October','July','March']

from itertools import product

l = [f"Who was name's job in month?" for name, job, month in product(*dictionary.values())]

print(l)

【讨论】:

【参考方案3】:

template 是一个字符序列,而不是您的代码所依赖的字流。 word 取值 W, h, o, , ...

快速解决方法可能是:为要替换的每个内容嵌套循环:

question_list = []
for name in dictionary["Name"]:
    for job in dictionary["Job"]:
        for month in dictionary["Month"]:
            new_sent = template[:]    # copy of template
            for old, new in [("Name", name), ("Job", job), ("Month", month)]:
                template.replace(old, new)
            question_list.append(new)

这仍然是非常暴力的,但处于您正在使用的编程级别。如果您想学习使用该软件包,可以将三重循环替换为 itertools.product。您还可以使用正则表达式自动替换尖括号中的单词。事实上,您可以将整个过程塞进一个单语句列表理解中,然后分配给 question_list

【讨论】:

【参考方案4】:

我的一种方法是......

template = "Who was <Name>'s <Job> in <Month>?"
dicValues = 'Name': ['John', 'Peter', 'Paul'], 'Job': ['Designer', 'Carpenter', 'Lawyer'], 'Month': ['October', 'July', 'March']

question_list=[]
for v in range(len(list(dicValues.values())[0])):
#for loop to identify how many values are contained for a single key
    tempFormed=template
    for k in dicValues.keys():
    #for loop to iterate through the keys Name, Job & Month
        Formed=tempFormed.replace(k,dicValues.get(k)[v])
        tempFormed = Formed
    question_list.append(Formed)
question_list

输出:

["Who was <John>'s <Designer> in <October>?",
 "Who was <Peter>'s <Carpenter> in <July>?",
 "Who was <Paul>'s <Lawyer> in <March>?"]

【讨论】:

以上是关于用多个字典值替换字符串中的单词?的主要内容,如果未能解决你的问题,请参考以下文章

选择多个用数组中的每个值替换一个单词

用字典值替换字符串中的字典键

用空字符串替换字典数组中的 NSNull 值

Python:用 re.sub 替换列表中的多个特定单词

替换字符串 C++ 位置 X 中的单词

替换多个字符串中的多个单词