列表解析式 && 生成器表达式
本文通过1个例子说明列表解析式与生成器表达式的用法与区别
如果想求出某个文件最长的行,用列表解析式的代码如下:
f = open('test.txt','r')
longest = 0
allLines = [ line.strip() for line in f.readlines()]
f.close() #此处关闭文件是因为当多个进程要读取某个文件时候,我们在读取所有行之后要尽快释放文件句柄
for line in allLines:
lineLen = len(line)
if lineLen > longest:
longest = lineLen
return longest
然而当处理大文件的时候,readlines()会读取文件的所有行,对于超大文件这样是不可行的,于是就有列表解析式,不需要讲所有行读入内存,而是迭代的过程中计算每行的长度。代码如下:
f = open('test.txt','r')
longest = 0
allLines = [len(line.strip()) for line in f]
f.close() #此处关闭文件是因为当多个进程要读取某个文件时候,我们在读取所有行之后要尽快释放文件句柄
return max(allLines)
上述写法是最优的吗?仔细想想,如果文件是超级大,尽管不需要把文件全部读入内存,但是却要维护1个文件每行长度的列表,也就是说allLines这个列表依旧很长,有没有其它方法呢?生成器表达式派上用场了,代码如下:
f = open('test.txt','r')
longest = max(len(line.strip()) for line in f)
f.close()
return longest
注意生成器表达式与列表解析式写法上的不同就是缺少”[]”, 生成器表达式依次迭代读入文件的行,并且返回迭代器,然后把迭代器作为max()的函数,求出最大行的长度,这个过程中是不需要维护任何列表的,也就避免了用列表解析式很消耗内存的缺点。
以下例子是1个最简单的生成器表达式
max(i for i in range(10))
>> 9