Python字符串:按照外观顺序快速汇总字符数

时间:2018-04-07 20:33:53

标签: python string python-3.x frequency

我想说我在Python3.x中有以下字符串

string1 = 'AAAAABBBBCCCDD'
string2 = 'CCBADDDDDBACDC'
string3 = 'DABCBEDCCAEDBB'

我想创建一个摘要"频率字符串"它按以下格式计算字符串中的字符数:

string1_freq = '5A4B3C2D'  ## 5 A's, followed by 4 B's, 3 C's, and 2D's
string2_freq = '2C1B1A5D1B1A1C1D1C' 
string3_freq = '1D1A1B1C1B1E1D2C1A1E1D2B' 

我的问题:

我如何快速创建这样的摘要字符串?

我的想法是:创建一个空列表来跟踪计数。然后创建一个for循环,检查下一个字符。如果匹配,请将计数增加+1并移至下一个字符。否则,追加到字符串的末尾' count' +'字符标识'。

Python的效率非常低。有更快的方法(也许使用下面的功能)?

有几种方法可以在python中计算字符串的元素。我喜欢collections.Counter,例如

from collections import Counter
counter_str1 = Counter(string1)
print(counter_str1['A']) # 5
print(counter_str1['B']) # 4
print(counter_str1['C']) # 3
print(counter_str1['D']) # 2

还有str.count(sub[, start[, end]

  

返回子字符串sub的非重叠出现次数   范围[开始,结束]。可选参数start和end是   解释为切片表示法。

举个例子:

print(string1.count('A'))  ## 5

2 个答案:

答案 0 :(得分:2)

我会使用itertools.groupby对相同字母的连续运行进行分组。然后在join中使用生成器表达式为每次运行创建计数和字母的字符串表示。

from itertools import groupby
def summarize(s):
    return ''.join(str(sum(1 for _ in i[1])) + i[0] for i in groupby(s))

实施例

>>> summarize(string1)
'5A4B3C2D'
>>> summarize(string2)
'2C1B1A5D1B1A1C1D1C'
>>> summarize(string3)
'1D1A1B1C1B1E1D2C1A1E1D2B'

答案 1 :(得分:2)

以下代码在不导入任何模块的情况下完成任务。

def freq_map(s):
    num = 0         # number of adjacent, identical characters
    curr = s[0]     # current character being processed
    result = ''     # result of function

    for i in range(len(s)):
        if s[i] == curr:
            num += 1
        else:
            result += str(num) + curr
            curr = s[i]
            num = 1

    result += str(num) + curr

    return result

注意:由于您根据性能要求了解决方案,我建议您使用此代码或其修改版本。

我已经针对CoryKramer提供的代码执行了粗略的性能测试,以供参考。该代码在58%的时间内执行相同的功能而不使用外部模块。可以找到代码段here