RLE(运行长度编码)模式似乎在我的工作中出现了很多。
它的本质是,每次您看到“中断”或您到达输入的末尾时,您都会输出自上次“中断”以来遇到的元素的减少。
(在实际的 RLE 中,'break' 只是这个字符与最后一个字符不匹配,但在现实世界中它通常稍微复杂一些,但仍然是当前和最后一个元素的函数。)
我想删除重复的 last_val != None: rle.append((last_val, count)) 条件和 Action ,它们在循环中和结束时都出现。
问题是:
- 用函数调用替换它们会产生更多而不是更少的代码。
- 保持命令式风格(例如,在 Haskell 中,问题就消失了)。
命令式 Python 代码是:
#!/usr/bin/env python
data = "abbbccac"
if __name__ == '__main__':
rle = []
last_val = None
count = 0;
for val in data:
if val != last_val and last_val != None:
rle.append((last_val, count))
count = 1
else:
count += 1
last_val = val
if last_val != None:
rle.append((last_val, count))
print rle
附言用函数式语言可以简单地解决:
#!/usr/bin/env runhaskell
import Data.List (group)
dat = "abbbccac"
rle :: Eq a => [a] -> [(a, Int)]
rle arr = map (\g -> (head g, length g)) $ group arr
main :: IO ()
main = print $ rle dat
请您参考如下方法:
使用 Python“包含电池”可以轻松解决:
>>> data = "abbbccac"
>>> from itertools import groupby
>>> ilen = lambda gen : sum(1 for x in gen)
>>> print [(ch, ilen(ich)) for ch,ich in groupby(data)]
[('a', 1), ('b', 3), ('c', 2), ('a', 1), ('c', 1)]
groupby 返回 2 元组的迭代器。第一个是表示下一组的值,第二个是可用于迭代组中项目的迭代器。您只需要组的长度,但不能直接获取长度,因此我添加了简单的 ilen lambda 函数来计算迭代器的长度。
