Skip to main content
 首页 » 编程设计

python之如何交换一串十六进制字节中的相邻字节(有或没有正则表达式)

2025年05月04日23小虾米

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

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

我想要的结果是 “34127856”

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

请您参考如下方法:

正则表达式方法:

import re 
twopairs = re.compile(r'(..)(..)') 
stringwithswappedwords = twopairs.sub(r'\2\1', basestring) 
twoquads = re.compile(r'(....)(....)') 
stringwithswappedlongs = twoquads.sub(r'\2\1', stringwithswappedwords) 

编辑: 然而,这绝对不是 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) 

请注意,我设置了 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 

...并且您发现在这种情况下,RE-less 方法的速度提高了大约 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) 

这给出:

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

大约 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) 

这给出:

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

进一步提高速度。