Python 的运行长度编码输出

Posted

技术标签:

【中文标题】Python 的运行长度编码输出【英文标题】:Run-Length Encoding Output for Python 【发布时间】:2020-06-09 20:59:53 【问题描述】:

这些是我需要执行行程编码分配的规则:

    独立角色将保持不变。例如“a”→[“a”]。 一个字符 c 重复 N 次的运行将被压缩为 ["c", "c", N]。 例如。 "bbbb" → ['b', 'b', 4]。

这就是我的目标输出的样子 "aaaabbcccd" → ['a', 'a', 4, 'b', 'b', 2, 'c', 'c', 3, 'd' ] 以我希望的方式工作。 但是,这是 "abcd" → ['a', 'a', 1, 'b', 'b', 1, 'c', 'c', 1, d] 和 我正在寻找这样的输出 "abcd" → ['a', 'b', 'c', 'd']

string = "aaaabbcccd"

def encode(string):
    counter = 1
    result = ""
    previousLetter = string[0]
    if len(string)==1:
      return string[0]

    for i in range(1,len(string),1):
        if not string[i] == previousLetter:
            result += string[i-1] + string[i-1] + str(counter) 
            previousLetter = string[i]
            counter = 1
        else:
            counter += 1

        if i == len(string)-1:
                result += string[i]

    return result

result = encode(string)
print(result)

我知道这与这一行有关:result += string[i-1] + string[i-1] + str(counter) 所以我正在考虑为角色出现的次数提供某些条件,但在组合到代码中时它不再起作用。也许我可以在第一个代码中更改一些内容来解决问题,而无需执行此额外代码部分,但我目前不知道?

if str(counter) == 1:
    result += string[i]
if str(counter) == 2:    
    result += string[i] + string[i] 
else:
    result += string[i] + string[i] + str(counter)

【问题讨论】:

您是否正在寻找对当前代码或其他可能更简单的代码的修复? 无论哪种方式都可以,只要它可以工作,但可能是用于学习目的的更简单的代码。 【参考方案1】:

这应该做你想做的:

def encode(string):
    string_len = len(string)
    i = 0
    result = []
    while i < string_len:
        count = 1
        c = string[i]
        i += 1
        while i < string_len and string[i] == c:
            count += 1
            i += 1
        if count == 1:
            result.append(c)
        else:
            result += [c, c, count]
    return result

它计算每个新字符的运行长度,然后根据长度是 1 还是大于 1,将适当的条目添加到结果列表中。

【讨论】:

谢谢!虽然,我花了一些时间来理解它的含义,它做了我想做的事情,非常感谢!【参考方案2】:

如果你有Python3.8,感谢walrus operator:

Python 3.8.1 (default, Jan  8 2020, 14:26:07)
[GCC 7.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from itertools import groupby, chain
>>> string = "aaaabbcccd"
>>> encoded = [*chain(*[[k, k, length] if (length := len([*g])) > 1 else [k] for k, g in groupby(string)])]
>>> print(encoded)
['a', 'a', 4, 'b', 'b', 2, 'c', 'c', 3, 'd']

【讨论】:

感谢您的帮助!我从没想过它可以与一行代码一起工作,但我在 Jupyter Notebook 中没有 Python3.8。【参考方案3】:

您可以使用 zip 将字符串偏移一,使您的循环更简单。

st = "aaaabbcccd"

li = []
i=0
for c1,c2 in zip(st,st[1:]):
    i+=1
    if c1 != c2:
        li += [c1,c1,i]
        i=0

li += [c2]   
print(li)

输出:

['a', 'a', 4, 'b', 'b', 2, 'c', 'c', 3, 'd']   

【讨论】:

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

python有关改变标准输出的默认编码的问题

python运行显示编码错误

python输出到文件乱码如何解决

CSDN|每日一练编码

CSDN|每日一练编码

Python2/3的中英文字符编码与解码输出: UnicodeDecodeError: 'ascii' codec can't decode/encode