【问题标题】:Replace numbers with letters and offer all permutations用字母替换数字并提供所有排列
【发布时间】:2021-10-14 06:49:15
【问题描述】:

在将数字转换为可能的视觉相似字母时,我需要确定具有数字的字符串的所有可能字母组合。

使用字典:

number_appearance = {
       '1': ['l', 'i'],
       '2': ['r', 'z'],
       '3': ['e', 'b'],
       '4': ['a'],
       '5': ['s'],
       '6': ['b', 'g'] ,
       '7': ['t'],
       '8': ['b'], 
       '9': ['g', 'p'],
       '0': ['o', 'q']} 

我想编写一个函数,它接受输入并创建所有可能的字母组合。例如:

text = 'l4t32'

def convert_numbers(text):
      return re.sub('[0-9]', lambda x: number_appearance[x[0]][0], text)

我希望输出是一个包含所有可能排列的列表:

['later', 'latbr', 'latbz', 'latez]

如果您只是从number_appearance 中获取每个列表中的第一个字母,则上述函数有效,但我正在尝试找出迭代所有可能组合的最佳方法。任何帮助将不胜感激!

【问题讨论】:

  • 这能回答你的问题吗? Get the cartesian product of a series of lists?
  • 我注意到在所有可能的排列列表中,您将r 替换为z,但您没有将l 替换为i。这是为什么呢?
  • 我只是用看起来像它们的字母替换数字。 l 不会被替换,因为它已经是一个字母。如果我使用数字1 而不是字母l,我会想要一个同时使用li 的版本。
  • 但是r 也已经是一封信了!我认为您需要从排列列表中删除 'latbz''latez'
  • 糟糕 - 这是我的错误 - 在示例中 r 应该是 2 :)

标签: python regex string replace itertools


【解决方案1】:

作为您自己答案的升级,我建议如下:

    def convert_numbers(text):
        all_items = [number_appearance.get(char, [char]) for char in text]
        return [''.join(elem) for elem in itertools.product(*all_items)]

改进之处在于:

  • 它不会将文本转换为列表(没有必要)
  • 你不需要正则表达式
  • 如果您决定还想在数字顶部添加其他字符,它仍然可以工作

【讨论】:

    【解决方案2】:
    def convert_num_appearance(text):
        string_characters = [character for character in text]
        
        all_items = []
    
        for item in string_characters:
            if re.search('[a-zA-Z]', item):
               all_items.append([item])
            elif re.search('\d', item):
               all_items.append(number_appearance[item])
    
        return [''.join(elem) for elem in itertools.product(*all_items)]
    

    【讨论】:

      【解决方案3】:

      我会这样分解问题:

      1. 首先,创建一个函数来替换给定的一组替换字母。我的输入规范是一个字母序列,其中第一个字母是'0' 字符的替换,接下来是1 等。这允许我使用该序列中的索引来确定要替换的字符,同时生成一个普通序列而不是字典或其他复杂结构。要进行替换,我将使用原始字符串的内置translate 方法。这需要in the documentation 描述的字典,我可以使用字典理解或提供的辅助方法str.maketransstr 类型的静态方法)轻松构建它。

      2. Use itertools.product 生成这些序列。

      3. 使用列表推导对每个序列应用替换。

      因此:

      from itertools import product
      
      def replace_digits(original, replacement):
          # translation = {ord(str(i)): c for i, c in enumerate(replacement)}
          translation = str.maketrans('0123456789', ''.join(replacement))
          print(translation)
          return original.translate(translation)
      
      replacements = product(
         ['o', 'q'], ['l', 'i'], ['r', 'z'], ['e', 'b'], ['a'],
         ['s'], ['b', 'g'] , ['t'], ['b'], ['g', 'p']
      )
      
      [replace_digits('14732', r) for r in replacements]
      

      (您会注意到结果中有重复项;这是因为对未出现在输入中的符号进行了变体替换。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-04
        • 2010-12-20
        • 1970-01-01
        • 2012-10-10
        相关资源
        最近更新 更多