Boa*_*Boa 1 python for-loop list-comprehension python-2.7
我问的原因是在合并各种数据结构,字典,列表,字符串.
bffer = ""
dict_size = 128
for character in string:
appnd_bffer = bffer + character
if appnd_bffer in codebook:
bffer = appnd_bffer
else:
output_list.append(codebook[bffer])
codebook[appnd_bffer] = dict_size
dict_size += 1
bffer = character
Run Code Online (Sandbox Code Playgroud)
我是列表理解的新手,所以如果有可能我真的可以使用解释.干杯.
循环当前取决于能够分配bffer
.因为赋值是一个语句,而列表推导只能包含表达式,所以将它转换为列表解析需要很多难以理解的可变对象技巧.
因此,将其转换为列表理解将导致无法读取的混乱,没有任何明显的好处(移除list.append()
调用的任何速度优势将被可变对象操作抵消).
为了让您了解为什么尝试将LZW压缩器的循环填充到列表理解中是一个非常糟糕的主意,我实际上已经开始编写一些疯狂的代码来实现这一点.
它使用了一些相当狡猾的技巧,它不适用于Python 3,因为在Python 3中,列表理解在其自己的范围内运行; 在Python 2中,列表理解在周围代码的范围内运行.这意味着我将原始缓冲区传递给list comp的技巧在Python 3中不起作用.
首先,这是包含在函数中的原始代码,带有几个变量名称更改,以及一些额外的附加功能,使其成为一个可运行的,可测试的示例.
from __future__ import print_function
def lzw_compress_Boa(data):
dict_size = 128
codebook = {chr(i): i for i in range(dict_size)}
output_list = []
oldbuff = ""
for ch in data:
newbuff = oldbuff + ch
if newbuff in codebook:
oldbuff = newbuff
else:
output_list.append(codebook[oldbuff])
codebook[newbuff] = dict_size
dict_size += 1
oldbuff = ch
return output_list
data = 'this data is this data'
output_list = lzw_compress_Boa(data)
print(output_list)
print(len(data), '->', len(output_list))
Run Code Online (Sandbox Code Playgroud)
产量
[116, 104, 105, 115, 32, 100, 97, 116, 97, 32, 130, 32, 128, 138, 133]
22 -> 15
Run Code Online (Sandbox Code Playgroud)
我们实际上并不需要将代码簿的大小保存在单独的变量中.像所有Python的内置容器类型一样,dict会跟踪它的大小,我们可以使用该len()
函数来获取它.所以我们可以替换这两行:
codebook[newbuff] = dict_size
dict_size += 1
Run Code Online (Sandbox Code Playgroud)
用这一行:
codebook[newbuff] = len(codebook)
Run Code Online (Sandbox Code Playgroud)
现在这是使用列表理解的疯狂版本.记住小孩,请 不要在家里试试!:)
def lzw_compress_crazy(data):
dict_size = 128
codebook = {chr(i): i for i in range(dict_size)}
def magic(oldbuff, ch):
newbuff = oldbuff + ch
if newbuff in codebook:
return [(newbuff, None)]
else:
codebook[newbuff] = len(codebook)
return [(ch, codebook[oldbuff])]
oldbuff = ""
return [result for ch in data
for oldbuff, result in magic(oldbuff, ch) if result]
Run Code Online (Sandbox Code Playgroud)
请注意,此版本不仅比我发布的第一个版本难以阅读,而且效率也较低.正如我在开始时所说的那样,它不那么便携,而且它使用了一些完全狡猾的技巧,这些技巧永远不会用在严肃的代码中.
列表理解很酷,一旦你习惯了它们,它们可以使你的代码更简洁,这有助于提高可读性,只要你不试图在它们中做太多.列表comp 比在"传统"样式循环中使用的等效代码稍微有效,但它们不是魔术,并且使用难以理解的列表理解而不是一个清晰可读的传统循环不是 Pythonic..append
for
for