我想说我在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
答案 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。