我要问的原因是,它包含各种数据结构,字典,列表,字符串。
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
我是列表理解的新手,所以如果有可能我真的可以使用解释。欢呼声。
答案 0 :(得分:8)
循环当前取决于能够分配给bffer
。因为赋值是一个语句,而列表推导只能包含表达式,所以将它转换为列表解析需要很多难以理解的可变对象技巧。 / p>
因此,将其转换为列表解析会导致无法读取的混乱,没有任何明显的好处(删除list.append()
调用的任何速度优势都将被可变对象操作所抵消。)
答案 1 :(得分:6)
只是为了让你知道为什么尝试将你的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))
<强>输出强>
[116, 104, 105, 115, 32, 100, 97, 116, 97, 32, 130, 32, 128, 138, 133]
22 -> 15
我们实际上并不需要将代码簿的大小保存在单独的变量中。像所有Python的内置容器类型一样,dict会跟踪它的大小,我们可以使用len()
函数来获取它。所以我们可以替换这两行:
codebook[newbuff] = dict_size
dict_size += 1
这一行:
codebook[newbuff] = len(codebook)
现在这里是使用列表理解的疯狂版本。记住小孩,请 不要在家尝试这个! :)
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]
请注意,此版本不仅比我发布的第一个版本难以阅读,而且效率也较低。正如我在开始时所说的那样,它不那么便携,而且它使用了一些完全狡猾的技巧,绝不应该用于严肃的代码。
列表理解很酷,一旦你习惯了它们,它们就可以使你的代码更简洁,这有助于提高可读性,只要你不试图在它们中做太多。在“传统”样式.append
循环中,使用for
的等效代码,列表组件略微 更高效,但它们不是魔术,而是使用难以理解的列表理解一个很好的清晰可读的传统for
循环是不 Pythonic。
答案 2 :(得分:2)
不,这不能成为列表理解,因为它包含除组成列表的表达式之外的表达式(例如dict_size += 1
)。这些表达式无法进入列表理解,因为理解的唯一目的是创建该对象。可能对您有所帮助的是创建一个单独的函数,其中包含循环的单次迭代的逻辑,然后在循环中使用该函数。