Tim*_*ara 8 python string immutability
如果我想进行多个字符串替换,那么最有效的方法是什么呢?
我旅行中遇到的一种情况如下:
>>> strings = ['a', 'list', 'of', 'strings']
>>> [s.replace('a', '')...replace('u', '') for s in strings if len(s) > 2]
['a', 'lst', 'of', 'strngs']
Run Code Online (Sandbox Code Playgroud)
Ale*_*lli 12
您给出的具体示例(删除单个字符)非常适合translate
字符串方法,单个字符替换单个字符也是如此.如果输入字符串是Unicode,那么,以及上面两种"替换",用该translate
方法替换具有多个字符串的单个字符也是好的(不过如果你需要处理字节字符串) .
如果你需要替换多个字符的子串,那么我还建议使用正则表达式 - 尽管不是@ gnibbler的回答推荐的方式; 相反,我建立正则表达式r'onestring|another|yetanother|orthis'
(加入你想要用竖线替换的子串 - 当然,re.escape
如果它们包含特殊字符,也要确保它们也是如此)并根据dict编写一个简单的替换函数.
我不会在这个时候提供很多代码,因为我不知道这两段中的哪一段适用于你的实际需要,但是(当我后来回到家并再次检查SO时;-)我将成为很高兴编辑以根据您对问题的编辑添加代码示例(比对此答案的评论更有用;-).
编辑:在评论中,OP说他想要一个"更一般"的答案(没有说明这意味着什么)然后在编辑他的Q时他说他想研究各种片段之间的"权衡",所有片段都使用单字符子串(并检查其存在,而不是按原始请求替换 - 当然是完全不同的语义).
考虑到这种完全混乱,我可以说是"检查权衡"(性能方面)我喜欢使用python -mtimeit -s'setup things here' 'statements to check'
(确保要检查的语句没有副作用以避免扭曲时间测量,因为timeit
隐式循环提供准确定时测量).
一般的答案(没有任何折衷,并且涉及多个字符的字符串,这样完全违背自己的Q的编辑,但辅音他的意见-这两者是完全矛盾的这是当然不可能同时满足):
import re
class Replacer(object):
def __init__(self, **replacements):
self.replacements = replacements
self.locator = re.compile('|'.join(re.escape(s) for s in replacements))
def _doreplace(self, mo):
return self.replacements[mo.group()]
def replace(self, s):
return self.locator.sub(self._doreplace, s)
Run Code Online (Sandbox Code Playgroud)
使用示例:
r = Replacer(zap='zop', zip='zup')
print r.replace('allazapollezipzapzippopzip')
Run Code Online (Sandbox Code Playgroud)
如果要替换的某些子字符串是Python关键字,则需要更少地直接传递它们,例如,以下内容:
r = Replacer(abc='xyz', def='yyt', ghi='zzq')
Run Code Online (Sandbox Code Playgroud)
会失败因为def
是关键字,所以你需要例如:
r = Replacer(abc='xyz', ghi='zzq', **{'def': 'yyt'})
Run Code Online (Sandbox Code Playgroud)
等等.
我发现这对于一个类(而不是程序编程)来说是一个很好的用途,因为RE要定位要替换的子串,表示要替换它们的dict,以及执行替换的方法,真的喊出来"保持一致" ",并且类实例是在Python中执行这种"保持在一起"的正确方法.一个闭包工厂也可以工作(因为该replace
方法实际上是实例中唯一需要在"外部"可见的部分),但是可能不那么清晰,难以调试:
def make_replacer(**replacements):
locator = re.compile('|'.join(re.escape(s) for s in replacements))
def _doreplace(mo):
return replacements[mo.group()]
def replace(s):
return locator.sub(_doreplace, s)
return replace
r = make_replacer(zap='zop', zip='zup')
print r('allazapollezipzapzippopzip')
Run Code Online (Sandbox Code Playgroud)
唯一真正的优势可能是一个很谦虚更好的性能(需要与检查timeit
的"标杆案例"考虑显著和代表使用它的应用程序)为获得"自由变量"( ,,replacements
在这种情况下)可能是比正常的,基于类的方法访问限定名称(等)要快得多(这是否是这种情况将取决于使用的Python实现,需要检查重要的基准测试!).locator
_doreplace
self.replacements
timeit
归档时间: |
|
查看次数: |
5184 次 |
最近记录: |