视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Python中迭代器和生成器以及列表的介绍(附代码)
2020-11-27 14:20:31 责编:小采
文档


这个语句的核心是 for 循环, 它迭代 iterable 对象的所有条目. 前边的 expr 应用于序列的每个成员, 最后的结果值是该表达式产生的列表。 迭代变量并不需要是表达式的一部分。例如用 lambda 函数计算序列成员的平方的表达是为:

map(lambda x: x ** 2, range(6))

这可以用列表解析来改写:

[x ** 2 for x in range(6)]

列表解析的表达式可以取代内建的 map() 函数以及 lambda , 而且效率更高。结合 if 语句,列表解析还提供了一个扩展版本的语法:

[expr for iter_var in iterable if cond_expr]

这个语法在迭代时会过滤/捕获满足条件表达式 cond_expr 的序列成员。例如挑选出序列中的奇数可以用下边的方法:

[x for x in seq if x % 2]

列表解析还有很多巧妙的应用:

迭代一个有三行五列的矩阵:

[(x+1,y+1) for x in range(3) for y in range(5)]

计算出所有非空白字符的数目:

f = open('hhga.txt', 'r')

len([word for line in f for word in line.split()])

生成器表达式

生成器表达式是列表解析的一个扩展。列表解析的一个不足就是必要生成所有的数据, 用以创建整个列表。这可能对有大量数据的迭代器有负面效应。生成器表达式通过结合列表解析和生成器解决了这个问题。生成器表达式在 Python 2.4 被引入, 它与列表解析非常相似,而且它们的基本语法基本相同; 不过它并不真正创建数字列表, 而是返回一个生成器,这个生成器在每次计算出一个条目后,把这个条目“产生”(yield)出来。生成器表达式使用了"延迟计算"(lazy evaluation), 所以它在使用内存上更有效。生成器表达式语法:

(expr for iter_var in iterable if cond_expr)

生成器并不会让列表解析废弃, 它只是一个内存使用更友好的结构, 基于此, 有很多使用生 成器地方,如下所示:

快速地计算文件大小:

上面我们用列表解析计算出了文件中非空白字符的数目,那么只要用 sum() 函数对每个单词的长度求和,则可大致计算出文件的大小。sum() 函数的参数不仅可以是列表,还可以是可迭代对象,比如生成器表达式。这里我们用生成器表达式改写整个过程:

sum(len(word) for line in data for word in line.split())

交叉配对:

生成器表达式就好像是懒惰的列表解析(这反而成了它主要的优势)。它还可以用来处理其他列表或生成器:

rows = [1, 2, 3, 17]

def cols(): # example of simple generator
 yield 56 
 yield 2 
 yield 1

x_product_pairs = ((i, j) for i in rows for j in cols())

for pair in x_product_pairs:
 print pair

寻找文件最长的行:

def longest(filename):
 glines = (x.strip() for x in open(filename))
 return max([len(l) for l in glines])

# Script starts from here

if __name__ == "__main__":
 print longest("/etc/hosts")

这个例子摘自 《Python核心编程》 中生成器表达式一节,作者在原书中只用了一行代码来实现这个功能,即:

return max(len(x.strip()) for x in open('/etc/motd'))

这行代码会报出如下错误:

TypeError: object of type 'generator' has no len()

也就是说生成器没有 len() 方法,所以这样并不可行,但是用列表解析则可以用一行实现:

return max([len(x.strip()) for x in open("/etc/motd")])

下载本文
显示全文
专题