【问题标题】:How to optimize three consecutive str.replace() calls? [duplicate]如何优化三个连续的 str.replace() 调用? [复制]
【发布时间】:2018-10-09 18:51:47
【问题描述】:
expr='9subtract5equal4'

expr = expr.replace('subtract', '-')
expr = expr.replace('plus', '+')
expr = expr.replace('equal', '==')

感觉最后三行代码很丑,所以尝试使用map等函数式编程函数进行优化。但我没有找到实现这一目标的好方法。有什么建议吗?

【问题讨论】:

  • “优化”是什么意思?跑得更快?使用更少的字符?使用更少的运行时内存?
  • 也许维护一个替换字典。
  • @usr2564301 我想使用更少的字符。
  • @Georgy 非常感谢,这正是我想要的!对不起,我的搜索能力很差......

标签: python replace


【解决方案1】:

你可以这样做:

def replace_all(text, dic):
  for i, j in dic.items():
    text = text.replace(i, j)
  return text

s = '9subtract5equal4'

d = {
  'subtract': '-',
  'plus': '+',
  'equal': '==',
}

s = replace_all(s, d)

【讨论】:

    【解决方案2】:

    老实说,我会按照您编写的方式编写它,但是如果您想“从功能上”执行它,您可能需要使用 functools.reduce,因为您需要将替换列表“减少”为单个结果:

    import functools
    
    expr = '9subtract5equal4'
    
    # a list of our replacements, as pairs
    REPLACEMENTS = [
        ('subtract', '-'),
        ('plus', '+'),
        ('equal', '=='),
    ]
    
    result = functools.reduce(
        lambda word, old_new: word.replace(old_new[0], old_new[1]),
        REPLACEMENTS,
        expr
    )
    

    这里我们只是“累加” lambda 函数的结果,它接受最后一个“累加”的单词和一个替换对,并调用.replace() 来获取下一个“累加”的单词。

    但实际上,这不是解决此问题的 Pythonic 方法(在 Python 3 中 reduce 被推入 functools 是有原因的),而且您的原始方法更好。

    【讨论】:

      【解决方案3】:
      1. 创建一个从操作数名称映射到符号的字典:

        ops = {'subtract':'-', 'add':'+', 'equal':'=='}
        

        你可以随心所欲,这显然是一种优化——添加更多操作数非常容易,不需要任何进一步的修改。

      2. 使用列表推导遍历您的表达式:

        [x if x.isdigit() else ops[x] for x in re.findall(r'\d+|[a-z]+',expr)]
        

        这使用正则表达式来分隔数字和操作数,所以 import re 在开头。正则表达式返回

        ['9', 'subtract', '5', 'equal', '4']
        

        列表推导式用字典中的项目替换非数字字符串。

      结果:

      ['9', '-', '5', '==', '4']
      

      所以你会使用

      expr = ''.join([x if x.isdigit() else ops[x] for x in re.findall(r'\d+|[a-z]+',expr)])
      

      得到你的输出

      '9-5==4'
      

      【讨论】:

        【解决方案4】:

        你可以这样做:

        expr = expr.replace('subtract', '-').replace('plus', '+').replace('equal', '==')
        

        或者,您可以循环使用 dictionary 的替换:

        replace = {'subtract': '-', 'plus': '+', 'equal': '='}
        for word in replace:
            expr = expr.replace(word, replace[word])
        

        【讨论】:

        • 你也可以使用正则表达式定义一个 lambda: "repl = lambda x: expr[x.group(0)]" 然后调用 "re.sub('subtract|equal', string="9subtract5equal4 ", repl=repl)" 其中 expr 是你的替换字典
        【解决方案5】:

        因为它的代码很好,但你可以在每一步直接操作返回值:

        expr='9subtract5equal4'
        
        expr = expr.replace('subtract', '-') \
            .replace('plus', '+') \
            .replace('equal', '==') 
        

        甚至

        expr = '9subtract5equal4' \
            .replace('subtract', '-') \
            .replace('plus', '+') \
            .replace('equal', '==') 
        

        【讨论】:

          猜你喜欢
          • 2014-04-09
          • 1970-01-01
          • 1970-01-01
          • 2021-07-07
          • 2013-12-21
          • 2014-09-09
          • 2017-09-23
          • 2013-07-04
          • 2019-02-25
          相关资源
          最近更新 更多