Python:无需外部库即可计算连续字符的最快方法

问题描述 投票:0回答:2

我有一个文本字符串,例如:

33 P DDD AA 00 23

我想计算所有连续的字符,以通过这些字符和计数器的翻译来创建一个新字符串。

我创建了一个运行良好的代码,但我需要提高执行时间,因此我正在寻找其他方法来做到这一点。

translate_dict = {
    "H": "Ab",
    "I": "Bb",
    "J": "Cb",
    "K": "Db",
    "L": "Eb",
    "M": "Fb",
    "N": "Gb",
    "O": "A#",
    "P": "B#",
    "Q": "C#",
    "R": "D#",
    "S": "E#",
    "T": "F#",
    "U": "G#",
    "0": "A",
    "1": "B",
    "2": "C",
    "3": "D",
    "4": "E",
    "5": "F",
    "6": "G",
    " ": "P",
}    

res = []
i = 0

duration = 0
while i < len(t):
    counter = 1
    while i+counter < len(t) and t[i] == t[i+counter]:
        counter +=1
    res.append(translate_dict.get(t[i], t[i]) + str(counter))
    duration += counter
    i += counter
    
return ''.join(res), duration

如果您需要更多信息,请随时询问!谢谢。

python algorithm optimization count duplicates
2个回答
0
投票

考虑利用 Python 内置的

itertools.groupby
,即不是 external 库:

from itertools import groupby


def old_translation(t: str, translate_dict: dict[str, str]) -> tuple[str, int]:
  res = []
  i = 0
  duration = 0
  while i < len(t):
    counter = 1
    while i + counter < len(t) and t[i] == t[i + counter]:
      counter += 1
    res.append(translate_dict.get(t[i], t[i]) + str(counter))
    duration += counter
    i += counter
  return ''.join(res), duration


def new_translation(t: str, translate_dict: dict[str, str]) -> tuple[str, int]:
  translated = ''.join(
      translate_dict.get(k, k) + str(len(list(g))) for k, g in groupby(t))
  duration = len(t)
  return translated, duration


translate_dict = {
    "H": "Ab",
    "I": "Bb",
    "J": "Cb",
    "K": "Db",
    "L": "Eb",
    "M": "Fb",
    "N": "Gb",
    "O": "A#",
    "P": "B#",
    "Q": "C#",
    "R": "D#",
    "S": "E#",
    "T": "F#",
    "U": "G#",
    "0": "A",
    "1": "B",
    "2": "C",
    "3": "D",
    "4": "E",
    "5": "F",
    "6": "G",
    " ": "P",
}
test_string = "33 P DDD AA 00 23"
print(f'{old_translation(test_string, translate_dict) = }')
print(f'{new_translation(test_string, translate_dict) = }')

输出:

old_translation(test_string, translate_dict) = ('D2P1B#1P1D3P1A2P1A2P1C1D1', 17)
new_translation(test_string, translate_dict) = ('D2P1B#1P1D3P1A2P1A2P1C1D1', 17)

0
投票

这是一种可能的优化:

def f2(t):
    res = []
    last = t[0]
    counter = 0
    duration = 0
    tr = translate_dict.get

    for c in t:
        if c == last:
            counter += 1
            continue
        res.append(tr(last, last) + str(counter))
        duration += counter
        last = c
        counter = 1

    res.append(tr(last, last) + str(counter))
    duration += counter

    return ''.join(res), duration

我的机器性能提高了约 2 倍。

© www.soinside.com 2019 - 2024. All rights reserved.