Python填充字符串格式的字符串

use*_*909 3 python format zip dictionary python-itertools

假设我有模板来填充dict中的值:

我有这样的模板:

templates = [
   "I have four {fruit} in {place}", 
   "I have four {fruit} and {grain} in {place}",
   ...
]
Run Code Online (Sandbox Code Playgroud)

使用这样的字典:

my_dict = {'fruit': ['apple', 'banana', 'mango'], 
           'place': ['kitchen', 'living room'],
           'grain' : ['wheat', 'rice']
          }
Run Code Online (Sandbox Code Playgroud)

说我有这样一句话:

sentence = "I have four apple in kitchen" 
Run Code Online (Sandbox Code Playgroud)

鉴于这句话,模板和字典,我想知道该句子匹配其中一个模板并返回它匹配的值,如下所示:

{'fruit': 'apple', 'place': 'kitchen'}
Run Code Online (Sandbox Code Playgroud)

和上面类似,如果:

Input: "I have four apple and wheat in kitchen"
Output: {'fruit': 'apple', 'grain': 'wheat', 'place': 'kitchen'}
Run Code Online (Sandbox Code Playgroud)

如果能够处理这个问题会很棒:

Input: "I have four apple in bedroom" 
Output: {'fruit': 'apple'}
Run Code Online (Sandbox Code Playgroud)

请注意,它只返回水果,而不是卧室,因为卧室不在地方的价值.

Mar*_*ers 6

将格式化的字符串转换为正则表达式

import re

words = {k: '(?P<{}>{})'.format(k, '|'.join(map(re.escape, v))) for k, v in my_dict.items()}
patterns = [re.compile(template.format(**words)) for template in templates]
Run Code Online (Sandbox Code Playgroud)

这会产生表格的图案I have four (?P<fruit>apple|banana|mango) in (?P<place>kitchen|living room)".匹配这些将为您提供预期的输出:

for pattern in patterns:
    match = pattern.match(sentence)
    if match:
        matched_words = match.groupdict()
Run Code Online (Sandbox Code Playgroud)

这是一种非常快速的O(N)方法来完全匹配句子:

>>> import re
>>> templates = [
...    "I have four {fruit} in {place}",
...    "I have four {fruit} and {grain} in {place}",
... ]
>>> my_dict = {'fruit': ['apple', 'banana', 'mango'],
...            'place': ['kitchen', 'living room'],
...            'grain' : ['wheat', 'rice']
...           }
>>> def find_matches(sentence):
...     for pattern in patterns:
...         match = pattern.match(sentence)
...         if match:
...             return match.groupdict()
...
>>> find_matches("I have four apple in kitchen")
{'fruit': 'apple', 'place': 'kitchen'}
>>> find_matches("I have four apple and wheat in kitchen")
{'fruit': 'apple', 'grain': 'wheat', 'place': 'kitchen'}
Run Code Online (Sandbox Code Playgroud)

如果您需要模板匹配部分句子,请将可选部分(?...)分组:

"I have four {fruit} in (?{place})"
Run Code Online (Sandbox Code Playgroud)

或添加\w+到单词列表(除了有效单词),然后在匹配后验证groupdict()结果my_dict.例如in bedroom,对于这种情况,\w+将匹配该bedroom部件,但不会在my_dict列表中找到place.