替换字符串中一组字符的最快方法

时间:2013-09-17 03:16:11

标签: python string performance replace

我正在使用一串字节(可以是10kb到3MB之间的任何地方),我需要过滤掉大约16个字节(用其他字节替换它们)

目前我的功能有点像这样......

BYTE_REPLACE = {
  52: 7, # first number is the byte I want to replace
  53: 12, # while the second number is the byte I want to replace it WITH
}
def filter(st):
  for b in BYTE_REPLACE:
    st = st.replace(chr(b),chr(BYTE_REPLACE[b]))
  return st

(为了这个问题,字节列表被解释)

使用map导致执行时间为〜.33s,而这导致〜。03s的快10倍(两者都在巨大的字符串上执行,压缩大于1.5MB)。

虽然任何性能提升都可以忽略不计,但还有更好的方法吗?

(我知道存储过滤后的字符串会更加优化。但这不是一个选项。我愚弄了Minecraft Classic服务器的级别格式,并且必须过滤掉某些客户端的字节不支持

3 个答案:

答案 0 :(得分:5)

使用str.translate

Python 3.x

def subs(st):
    return st.translate(BYTE_REPLACE)

使用示例:

>>> subs('4567')
'\x07\x0c67'

Python 2.x

str.translate (Python 2)

import string
k, v = zip(*BYTE_REPLACE.iteritems())
k, v = ''.join(map(chr, k)), ''.join(map(chr, v))
tbl = string.maketrans(k, v)
def subs(st):
    return st.translate(tbl)

答案 1 :(得分:4)

在字符串上查找translate()方法。这允许您在字符串上的一次传递中进行任意数量的1字节转换。使用string.maketrans()函数构建转换表。如果你通常有16对,这比16次替换1字节要快16倍。

答案 2 :(得分:0)

在您当前的设计中,每个字符串String.replace()次调用n次。虽然它最有可能是一种高效算法,但在3MB字符串上它可能会变慢。

如果在调用此函数时字符串已经包含在内存中,我会打赌最有效的方法是:

BYTE_REPLACE = {
  52: 7, # first number is the byte I want to replace
  53: 12, # while the second number is the byte I want to replace it WITH
}
def filter(st):
  st = list(st) # Convert string to list to edit in place :/
  for i,s in enumerate(st): #iterate through list
    if ord(s) in BYTE_REPLACE.keys():
        s[i]=chr(BYTE_REPLACE[ord(b)])
  return "".join(st) #return string

有一个很大的操作要在开始时创建一个新列表,另一个用于转换回字符串,但由于python字符串在您的设计中是不可变的,因此每个替换都会生成一个新字符串。

这完全基于猜想,可能是错误的。您需要使用实际数据进行测试。