Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 替换字符串中一组字符的最快方法_Python_String_Performance_Replace - Fatal编程技术网

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

Python 替换字符串中一组字符的最快方法,python,string,performance,replace,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_REP

我正在处理一个字节串(可以是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会导致执行时间缩短约0.33秒,而这会使执行时间缩短约0.03秒(两者都是在一个大于1.5MB压缩的大字符串上执行的)

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


(我知道存储过滤后的字符串会更好。不过,这不是一个选项。我在玩弄Minecraft Classic服务器级别的格式,必须过滤掉某些客户端不支持的字节)

在您当前的设计中,
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字符串在您的设计中是不可变的,因此每次替换都会生成一个新字符串


这一切都是基于猜测,可能是错误的。您需要使用实际数据对其进行测试。

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

使用:

Python3.x 用法示例:

>>> subs('4567')
'\x07\x0c67'
Python2.x


你读得怎么样?它是否来自文件系统,来自URL,是否已经全部存储在内存中?这可能会对最优化的方法产生很大的影响。它都在内存中可用(并且在每种情况下都直接传递给函数)。有一些情况下,一个字节会传递给这个函数-这是可以忽略的,我不会为此烦恼。有多少对是在
byte\u REPLACE
中?通常只有2到16英镑。对于完整列表和相当大的loadtest级别(512*512*256字节未压缩),完全替换(使用str.replace)需要.03s,在这里可能会有所帮助。使用str.translate的速度大约是我以前的两倍。
>>> subs('4567')
'\x07\x0c67'
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)