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

时间:2018-08-22 19:54:41

标签: python list dictionary replace string-matching

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

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来访问字典值列表中的每个项目,但是我没有足够的经验来知道我搞砸了。我该如何解决?

4 个答案:

答案 0 :(得分:2)

您可以使用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?"]

答案 1 :(得分: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)

答案 2 :(得分:1)

template是一个字符序列,而不是代码所依赖的单词流。 word取值为Who,...

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

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

答案 3 :(得分:0)

我的方法之一是...

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>?"]