将字典列表中的值映射到 Python 中的字符串

Posted

技术标签:

【中文标题】将字典列表中的值映射到 Python 中的字符串【英文标题】:Mapping values from a dictionary's list to a string in Python 【发布时间】:2022-01-16 09:36:14 【问题描述】:

我正在研究这样的句子结构:

sentence = "PERSON is ADJECTIVE"
dictionary = "PERSON": ["Alice", "Bob", "Carol"], "ADJECTIVE": ["cute", "intelligent"]

我现在需要所有可能的组合来从字典中形成这个句子,例如:

Alice is cute
Alice is intelligent
Bob is cute
Bob is intelligent
Carol is cute
Carol is intelligent

上面的用例比较简单,用下面的代码就完成了

dictionary = "PERSON": ["Alice", "Bob", "Carol"], "ADJECTIVE": ["cute", "intelligent"]

for i in dictionary["PERSON"]:
    for j in dictionary["ADJECTIVE"]:
        print(f"i is j")

但是我们是否也可以将其扩大到更长的句子?

例子:

sentence = "PERSON is ADJECTIVE and is from COUNTRY" 
dictionary = "PERSON": ["Alice", "Bob", "Carol"], "ADJECTIVE": ["cute", "intelligent"], "COUNTRY": ["USA", "Japan", "China", "India"]

这应该再次提供所有可能的组合,例如:

Alice is cute and is from USA
Alice is intelligent and is from USA
.
.
.
.
Carol is intelligent and is from India

我尝试使用 https://www.pythonpool.com/python-permutations/ ,但句子都被混淆了 - 但是我们如何才能固定几个单词,比如在这个例子中,单词 "and is from" 是固定的

基本上,如果字典中的任何键与字符串中的单词相等,则该单词应替换为字典中的值列表。

任何想法都会很有帮助。

【问题讨论】:

如果您需要入门帮助,我会看看 itertools.product(*dictionary.values()) 为您提供什么, 你可能想把你的句子转换成str.format()知道如何处理的东西,这样你就不必自己做replace的东西了。 【参考方案1】:

我的答案将基于 itertools.productzip 两个构建块。

itertools.product 将允许我们获取字典列表值的各种组合

zip 与原始键和上面的组合将允许我们创建可以与replace 一起使用的元组列表。

import itertools

sentence = "PERSON is ADJECTIVE and is from COUNTRY"
dictionary = "PERSON": ["Alice", "Bob", "Carol"], "ADJECTIVE": ["cute", "intelligent"], "COUNTRY": ["USA", "Japan", "China", "India"]

keys = dictionary.keys()
for values in itertools.product(*dictionary.values()):
    new_sentence = sentence
    for tpl in zip(keys, values):
        new_sentence = new_sentence.replace(*tpl)
    print(new_sentence)

如果你恰好有能力控制“句子”模板,你可以这样做:

sentence = "PERSON is ADJECTIVE and is from COUNTRY"

然后您可以将其简化为:

sentence = "PERSON is ADJECTIVE and is from COUNTRY"
dictionary = "PERSON": ["Alice", "Bob", "Carol"], "ADJECTIVE": ["cute", "intelligent"], "COUNTRY": ["USA", "Japan", "China", "India"]

keys = dictionary.keys()
for values in itertools.product(*dictionary.values()):
    new_sentence = sentence.format(**dict(zip(keys, values)))
    print(new_sentence)

两者都应该给你这样的结果:

Alice is cute and is from USA
Alice is cute and is from Japan
...
Carol is intelligent and is from China
Carol is intelligent and is from India

请注意,模板中出现的顺序并不重要,两种解决方案都应使用以下模板:

sentence = "PERSON is from COUNTRY and is ADJECTIVE"

或者情况2

sentence = "PERSON is from COUNTRY and is ADJECTIVE"

跟进:

如果字典有可能包含不在句子模板中的项目,会发生什么?目前,这并不理想,因为使用product() 生成句子的方式假设所有键都是,我们目前会生成重复。

最简单的解决方法是确保字典只有感兴趣的键...

在第一种情况下,这可能会这样做。

dictionary = key: value for key, value in dictionary.items() if key in sentence

或者在第二种情况下:

dictionary = key: value for key, value in dictionary.items() if f"key" in sentence

【讨论】:

非常感谢,这很好用,但是如果句子不包含字典中的所有键 sentence = "PERSON is ADJECTIVE" dictionary = "PERSON": ["Alice", "Bob", "Carol"], "ADJECTIVE": ["cute", "intelligent"], "COUNTRY": ["USA", "Japan", "China", "India"] 任何关于如何避免这种情况的想法,而不使用集合删除重复项。我想保持顺序,所以我不需要设置来删除重复项。 这是一个有趣的转折。让我更新答案... 非常感谢@jonsg 的后续解决方案。这是一个快速、简单且出色的解决方案!!我尝试了一个带有“PERSON is ADJECTIVE 和 ADJECTIVE”的句子,目的是获得“Alice 很可爱很聪明”这样的组合,但是由于我们使用替换,输出结果是“Alice 很可爱很可爱”,“Alice 很聪明”和聪明”。这句话没问题,但有没有可能得到“爱丽丝又可爱又聪明”这样的组合呢?任何建议都会有很大帮助,我非常感激。谢谢!【参考方案2】:

您可以先将sentence 中的字典键替换为,这样您就可以轻松地在循环中格式化字符串。然后你可以使用itertools.product 来创建dictionary.values() 的笛卡尔积,这样你就可以简单地循环它来创建你想要的句子。

from itertools import product
sentence = ' '.join([('' if w in dictionary else w) for w in sentence.split()])
mapped_sentences_generator = (sentence.format(*tple) for tple in product(*dictionary.values()))
for s in mapped_sentences_generator:
    print(s)

输出:

Alice is cute and is from USA
Alice is cute and is from Japan
Alice is cute and is from China
Alice is cute and is from India
Alice is intelligent and is from USA
Alice is intelligent and is from Japan
Alice is intelligent and is from China
Alice is intelligent and is from India
Bob is cute and is from USA
Bob is cute and is from Japan
Bob is cute and is from China
Bob is cute and is from India
Bob is intelligent and is from USA
Bob is intelligent and is from Japan
Bob is intelligent and is from China
Bob is intelligent and is from India
Carol is cute and is from USA
Carol is cute and is from Japan
Carol is cute and is from China
Carol is cute and is from India
Carol is intelligent and is from USA
Carol is intelligent and is from Japan
Carol is intelligent and is from China
Carol is intelligent and is from India

请注意,这适用于 Python >3.6,因为它假定字典插入顺序保持不变。对于较旧的 Python,必须使用 collections.OrderedDict 而不是 dict

【讨论】:

虽然这在这种特定情况下有效,但它有点脆弱,因为如果更改句子以使其与键的顺序不一致,它将失败。例如sentence = "PERSON is from COUNTRY and is ADJECTIVE" 将给出一个Carol is from cute and is USA

以上是关于将字典列表中的值映射到 Python 中的字符串的主要内容,如果未能解决你的问题,请参考以下文章

字典(当索引不好用时)

给定一个字符串列表,如果任何值等于列表中的值,我想将字典的值添加到新字典中[重复]

使用宽松字典映射列中的值

第4章 字典:当索引不好用时

Python:如何将字典中的值提取到列表中->当前在结果中获取 dict_values() [重复]

python 字典列表字符串 之间的转换