如何交换十六进制字节字符串中的相邻字节(使用或不使用正则表达式)

pyN*_*Guy 2 python regex string hex

给定字符串(或具有偶数个单词对的任何长度字符串):“12345678”

我如何交换相邻的“单词”?

我想要的结果是“34127856”

另外,完成后我需要交换多头。我想要的结果是:“78563412”

Ale*_*lli 5

正则表达式方法:

import re
twopairs = re.compile(r'(..)(..)')
stringwithswappedwords = twopairs.sub(r'\2\1', basestring)
twoquads = re.compile(r'(....)(....)')
stringwithswappedlongs = twoquads.sub(r'\2\1', stringwithswappedwords)
Run Code Online (Sandbox Code Playgroud)

编辑:然而,这绝对不是 Python 中最快的方法——这是人们发现这些事情的方法:首先,将所有“竞争”方法写入一个模块,在这里我称之为'swa.py'......:

import re

twopairs = re.compile(r'(..)(..)')
twoquads = re.compile(r'(....)(....)')

def withre(basestring, twopairs=twopairs, twoquads=twoquads):
  stringwithswappedwords = twopairs.sub(r'\2\1', basestring)
  return twoquads.sub(r'\2\1', stringwithswappedwords)

def withoutre(basestring):
  asalist = list(basestring)
  asalist.reverse()
  for i in range(0, len(asalist), 2):
    asalist[i+1], asalist[i] = asalist[i], asalist[i+1]
  return ''.join(asalist)

s = '12345678'
print withre(s)
print withoutre(s)
Run Code Online (Sandbox Code Playgroud)

请注意,我设置s并尝试了两种方法来进行快速健全性检查,以确保它们实际上计算出相同的结果 - 一般来说,对于这种“面对面的性能竞赛”来说,这是很好的实践!

然后,在 shell 提示符下使用timeit,如下所示:

$ python -mtimeit -s'import swa' 'swa.withre(swa.s)'
78563412
78563412
10000 loops, best of 3: 42.2 usec per loop
$ python -mtimeit -s'import swa' 'swa.withoutre(swa.s)'
78563412
78563412
100000 loops, best of 3: 9.84 usec per loop
Run Code Online (Sandbox Code Playgroud)

...您发现在这种情况下,无 RE 方法的速度大约快 4 倍,这是一个值得优化的结果。一旦您有了这样的“测量工具”,当然,如果在此操作中需要“真正的速度”,就可以轻松地尝试进一步的替代方案和调整以进一步优化。

编辑:例如,这是一种更快的方法(添加到相同swa.py的方法中,当然还有最后一行print faster(s);-):

def faster(basestring):
  asal = [basestring[i:i+2]
          for i in range(0, len(basestring), 2)]
  asal.reverse()
  return ''.join(asal)
Run Code Online (Sandbox Code Playgroud)

这给出:

$ python -mtimeit -s'import swa' 'swa.faster(swa.s)'
78563412
78563412
78563412
100000 loops, best of 3: 5.58 usec per loop
Run Code Online (Sandbox Code Playgroud)

大约 5.6 微秒(最简单的无 RE 方法的大约 9.8 微秒)是另一个可能有价值的微优化。

当然,等等——有一个古老的民间(伪)定理说任何程序都可以缩短至少一个字节,至少加快一纳秒……;-)

编辑:为了“证明”伪定理,这是一种完全不同的方法(替换 的结尾swa.py)...:

import array
def witharray(basestring):
  a2 = array.array('H', basestring)
  a2.reverse()
  return a2.tostring()

s = '12345678'
# print withre(s)
# print withoutre(s)
print faster(s)
print witharray(s)
Run Code Online (Sandbox Code Playgroud)

这给出:

$ python -mtimeit -s'import swa' 'swa.witharray(swa.s)'
78563412
78563412
100000 loops, best of 3: 3.01 usec per loop
Run Code Online (Sandbox Code Playgroud)

以获得进一步可能值得的加速。