Подход регулярного выражения:
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
и опробовал два подхода для быстрой проверки работоспособности, что они на самом деле вычисляют один и тот же результат - в общем, хорошая практика для такого рода "гонок на равных"!
Затем в приглашении оболочки вы используете 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 работает примерно в 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 микросекунд, по сравнению с 9,8 для простейшего подхода без RE, - это еще одна полезная микрооптимизация.
И так далее, конечно, есть старая народная (псевдо) теорема, которая гласит, что любую программу можно сделать как минимум на один байт короче и как минимум на одну наносекунду быстрее ...; -)
Редактировать : и, чтобы "доказать" псевдореему, вот совершенно другой подход (замените конец 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
для дальнейшего возможного ускорения.