【问题标题】:Create string combination based on replacement基于替换创建字符串组合
【发布时间】:2020-10-05 00:03:03
【问题描述】:

给定一个单词和一个替换字符字典,我需要根据替换形成一个字符组合

输入

word = 'accompanying'  
substitutions={'c':['$'], 'a': ['4'], 'g': ['9']} 

输出

{'a$$ompanyin9', 'ac$ompanyin9','a$companyin9','4ccomp4nying', '4$$omp4nying', 
'4$comp4nying','4c$omp4nying', '4ccomp4nyin9', 'a$$ompanying', 'a$companying', 'ac$ompanying', 
'accompanyin9', 'accompanying', '4$$omp4nyin9', '4$comp4nyin9', '4c$omp4nyin9','etc.,'}

我写了一个代码,但它并没有提供我期望的所有组合

示例代码

from itertools import product
substitutions={'c':['$'], 'a': ['4'], 'g': ['9']}
for key in substitutions.keys():
  if key not in substitutions[key]:
    substitutions[key].append(key)
wordPossibilities = []
word = 'accompanying'
for substitute in [zip(substitutions.keys(),ch) for ch in product(*substitutions.values())]:
  temp=word
  for replacement in substitute:
    temp=temp.replace(*replacement)
  wordPossibilities.append(temp)
print(set(wordPossibilities))

我的输出

{'4$$omp4nyin9', 'a$$ompanyin9', 'a$$ompanying', 'accompanyin9',
'accompanying', '4ccomp4nyin9', '4$$omp4nying', '4ccomp4nying'}

如果找到替换,我的代码将替换提供的字符串中的所有字符。如何根据索引进行替换以找到所有可能的组合?

【问题讨论】:

    标签: python python-3.x combinations itertools


    【解决方案1】:

    使用带有递归的生成器是简洁明了的:

    word = 'accompanying'  
    subs={'c':['$'], 'a': ['4'], 'g': ['9']} 
    def get_subs(d, c = []):
      if not d:
         yield ''.join(c)
      else:
         for i in [d[0], *subs.get(d[0], [])]:
            yield from get_subs(d[1:], c+[i])
    
    print(list(get_subs(word)))
    

    输出:

    ['accompanying', 'accompanyin9', 'accomp4nying', 'accomp4nyin9', 'ac$ompanying', 'ac$ompanyin9', 'ac$omp4nying', 'ac$omp4nyin9', 'a$companying', 'a$companyin9', 'a$comp4nying', 'a$comp4nyin9', 'a$$ompanying', 'a$$ompanyin9', 'a$$omp4nying', 'a$$omp4nyin9', '4ccompanying', '4ccompanyin9', '4ccomp4nying', '4ccomp4nyin9', '4c$ompanying', '4c$ompanyin9', '4c$omp4nying', '4c$omp4nyin9', '4$companying', '4$companyin9', '4$comp4nying', '4$comp4nyin9', '4$$ompanying', '4$$ompanyin9', '4$$omp4nying', '4$$omp4nyin9']
    

    不过,itertools.product 可用于更短的解决方案:

    from itertools import product as prod
    s = ''.join('{}' if i in subs else i for i in word)
    result = [s.format(*i) for i in prod(*[[i, *subs[i]] for i in word if i in subs])]
    

    输出:

    ['accompanying', 'accompanyin9', 'accomp4nying', 'accomp4nyin9', 'ac$ompanying', 'ac$ompanyin9', 'ac$omp4nying', 'ac$omp4nyin9', 'a$companying', 'a$companyin9', 'a$comp4nying', 'a$comp4nyin9', 'a$$ompanying', 'a$$ompanyin9', 'a$$omp4nying', 'a$$omp4nyin9', '4ccompanying', '4ccompanyin9', '4ccomp4nying', '4ccomp4nyin9', '4c$ompanying', '4c$ompanyin9', '4c$omp4nying', '4c$omp4nyin9', '4$companying', '4$companyin9', '4$comp4nying', '4$comp4nyin9', '4$$ompanying', '4$$ompanyin9', '4$$omp4nying', '4$$omp4nyin9']
    

    【讨论】:

    • 感谢您的代码。这有助于我了解有关编写递归代码的更多信息
    【解决方案2】:

    显然,您需要重写逻辑以考虑所需字母的单个实例,而不是每个唯一字母。查找所有出现的所需字母;使用 itertools 获取幂集;对幂集的每个元素进行指定的替换。 power_set 来自 this SO answer。我在某些地方留下了“爆炸”的代码,以便更容易地显示逻辑。您可能希望将最终循环包装成单行 return 表达式。

    from itertools import chain, combinations
    
    def power_set(iterable):
        s = list(iterable)
        return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
                                   
    substitutions={'c':['$'], 'a': ['4', 'a'], 'g': ['9']}
    word = 'accordingly'
    
    # Get index of each desired letter and its poosible substitutions
    sub_idx = [(pos, letter, sub_letter) for pos, letter in enumerate(word)
                if letter in list(substitutions.keys()) for sub_letter in substitutions[letter]]
    print("Replacement set", sub_idx)
    
    for possibility in power_set(sub_idx):
        # Make each of the substitutions indicated in the power set
        new_word = list(word)
        for pos, _, sub_letter in possibility:
            new_word[pos] = sub_letter
        print(''.join(new_word))
    

    输出:

    Replacement set [(0, 'a', '4'), (0, 'a', 'a'), (1, 'c', '$'), (2, 'c', '$'), (8, 'g', '9')]
    accordingly
    4ccordingly
    accordingly
    a$cordingly
    ac$ordingly
    accordin9ly
    accordingly
    4$cordingly
    4c$ordingly
    4ccordin9ly
    a$cordingly
    ac$ordingly
    accordin9ly
    a$$ordingly
    a$cordin9ly
    ac$ordin9ly
    a$cordingly
    ac$ordingly
    accordin9ly
    4$$ordingly
    4$cordin9ly
    4c$ordin9ly
    a$$ordingly
    a$cordin9ly
    ac$ordin9ly
    a$$ordin9ly
    a$$ordingly
    a$cordin9ly
    ac$ordin9ly
    4$$ordin9ly
    a$$ordin9ly
    a$$ordin9ly
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-11
      • 2013-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-05
      • 1970-01-01
      相关资源
      最近更新 更多