带有列表理解的 Python 中的运行长度编码

Posted

技术标签:

【中文标题】带有列表理解的 Python 中的运行长度编码【英文标题】:Run Length Encoding in Python with List Comprehension 【发布时间】:2014-10-21 14:54:11 【问题描述】:

与已回答的有关此主题的许多问题相比,我有一个更基本的运行长度编码问题。本质上,我正在尝试获取字符串

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>

如果有人有任何关于更有效的方法来解决此类问题的其他 cmets,我会全力以赴!

【问题讨论】:

Run length encoding in Python的可能重复 【参考方案1】:

你可以使用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'

【讨论】:

感谢完美!我了解代码 [list(g) for k, g in groupby(string)] 的工作原理,但我在第一部分被抓住了。您正在做的是说我有一个长度为 0 的字符串,并且我想在该字符串中加入较大列表中较小列表的总和。我迷路的地方是 join([''.format(k, sum(1 for _ in g)) 我想知道你是否可以更详细地解释一下它是如何工作的? @ADT:空字​​符串是连接符,放在生成的列表元素之间。例如,试试' - '.join(']['foo', 'bar', 'spam']) 并改变那个细木工。也可以试试[''.format(k, sum(1 for _ in g)) for k, g in groupby(string)] 列表解析产生的just【参考方案2】:

考虑使用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(f"x[0]x[1]" for x in mit.run_length.encode(iterable))  # python 3.6
# 'a2b1c4a3'

"".join(x[0] + str(x[1]) for x in mit.run_length.encode(iterable))
# 'a2b1c4a3'

替代迭代工具/功能样式:

"".join(map(str, it.chain.from_iterable(x for x in mit.run_length.encode(iterable))))
# 'a2b1c4a3'

注意:more_itertools 是一个第三方库,可以通过pip install more_itertools 安装。

【讨论】:

【参考方案3】:

我是一名 Python 初学者,这是我为 RLE 编写的。

s = 'aabccccaaa'
grouped_d = [(k, len(list(g))) for k, g in groupby(s)]

result = ''
for key, count in grouped_d:
    result += key + str(count)

print(f'result = result')

【讨论】:

以上是关于带有列表理解的 Python 中的运行长度编码的主要内容,如果未能解决你的问题,请参考以下文章

Python 类中的列表理解范围规则是啥? [复制]

带有 lambda 的 Python 列表理解 [重复]

如何修复 AttributeError:“列表”对象没有属性“编码”

Python geopy地理编码器中的超时错误

快速理解python2中的编码问题

从python中的字符串列表创建给定长度的随机列表