2014-08-27 34 views
2

与已经回答的许多关于此主题的问题相比,我有一个更基本的运行长度编码问题。从本质上讲,我试图把字符串带有列表理解的Python中的运行长度编码

string = 'aabccccaaa' 

,并使其返回

a2b1c4a3 

我想,如果我能设法让所有的信息到列表像我有如下图所示,我将能够轻松地返回a2b1c4a3

test = [['a','a'], ['b'], ['c','c','c','c'], ['a','a','a']] 

我想出了下面的代码,到目前为止,但不知道是否有人能帮助我弄清楚如何使创建输出I画家上面已经提到过。

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> 

如果任何人有任何关于更有效的方法来解决这样的问题有任何额外的意见,我都耳朵!

回答

3

您可以使用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' 
+0

谢谢完美!我理解代码[list(g)for k,g in groupby(string)]是如何工作的,但我在第一部分中被捕获。你在做什么是说我有一个长度为0的字符串,并且我想要加入那个字符串来加入较大列表中较小列表的总和。我失去了在片联合(['{} {}'。format(k,sum(1 for _in g)),我想知道你是否可以更详细地解释它的工作原理? – 2014-08-29 19:38:22

+0

@ADT:空字​​符串是连接符,放在所产生列表的元素之间。例如尝试'' - '.join('] ['foo','bar','spam'])'不同的木匠。也试试什么*只是'['{} {}'。格式(k,sum(1 for _in g))for k,g in groupby(string)]'list comprehension产生。 – 2014-08-29 20:19:42

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进行安装。