与许多有关此主题的问题相比,我有一个更基本的运行长度编码问题。基本上,我正在尝试取字符串
string = 'aabccccaaa'
并让它返回
a2b1c4a3
我认为如果我可以设法将所有信息放入列表中,如下所示,我很容易就能返回a2b1c4a3
test = [['a','a'], ['b'], ['c','c','c','c'], ['a','a','a']]
到目前为止,我想出了以下代码,但是想知道是否有人能够帮我弄清楚如何创建我上面说明的输出。
def string_compression():
for i in xrange(len(string)):
prev_item, current_item = string[i-1], string[i]
print prev_item, current_item
if prev_item == current_item:
<HELP>
如果有人对更有效的方法解决这样的问题有任何其他意见,我全都听见了!
答案 0 :(得分:4)
您可以使用itertools.groupby()
:
from itertools import groupby
grouped = [list(g) for k, g in groupby(string)]
这将生成您的每个字母组作为列表列表。
您可以一步将其转换为RLE:
rle = ''.join(['{}{}'.format(k, sum(1 for _ in g)) for k, g in groupby(string)])
每个k
是被分组的字母,每个g
是一个迭代器,产生相同字母的N倍; sum(1 for _ in g)
表达式以最有效的方式计算它们。
演示:
>>> from itertools import groupby
>>> string = 'aabccccaaa'
>>> [list(g) for k, g in groupby(string)]
[['a', 'a'], ['b'], ['c', 'c', 'c', 'c'], ['a', 'a', 'a']]
>>> ''.join(['{}{}'.format(k, sum(1 for _ in g)) for k, g in groupby(string)])
'a2b1c4a3'
答案 1 :(得分:0)
考虑使用more_itertools.run_length
工具。
<强>演示强>
import more_itertools as mit
iterable = "aabccccaaa"
list(mit.run_length.encode(iterable))
# [('a', 2), ('b', 1), ('c', 4), ('a', 3)]
<强>代码强>
"".join(x[0] + str(x[1]) for x in mit.run_length.encode(iterable))
# 'a2b1c4a3'
替代itertools /功能样式:
"".join(map(str, it.chain.from_iterable(x for x in mit.run_length.encode(iterable))))
# 'a2b1c4a3'
注意:more_itertools
是可通过pip install more_itertools
安装的第三方库。