首页 > 解决方案 > re.sub() 具有副作用的替换函数

问题描述

今天我遇到了以下构造:

import re
l = list('1234')
print(re.sub('.', lambda _: l.pop(0), 'abcd'))

基本上,它subrepl具有副作用的功能一起使用。

抛开有争议的风格问题不谈,这个定义是否明确?

例如,我在文档中找不到任何地方可以保证以任何特定的顺序repl调用匹配项(实际上也没有完全一次,尽管官方措辞在某种程度上可以解释)。此代码是否存在任何其他问题,实际的或潜在的?

标签: pythonregexreplaceside-effects

解决方案


根据以下文件re.sub

返回通过将in的最左侧不重叠出现替换为 replacement获得的字符串。patternstringrepl

和:

Ifrepl是一个函数,每次出现不重叠的模式时都会调用它。

因此很明显,re.sub从左到右搜索并将每次出现的给定替换pattern为函数的返回值repl。所以是的,你的代码的行为是明确定义的。但是,它效率不高,因为您正在迭代地弹出列表的第一项,每次迭代需要O(n)的时间复杂度。您可以改为使用迭代器在O(1)时间内实现相同的副作用:

import re
i = iter('1234')
print(re.sub('.', lambda _: next(i), 'abcd'))

这也输出:

1234

推荐阅读