我正在从一本书中学习 Python,我遇到了这个例子:
M = [[1,2,3],
[4,5,6],
[7,8,9]]
G = (sum(row) for row in M) # create a generator of row sums
next(G) # Run the iteration protocol
由于我是一个绝对的初学者,并且作者没有对示例或 next() 函数提供任何解释,所以我不明白代码在做什么。
该表达式(sum(row) for row in M)
创建了所谓的生成器。sum(row)
此生成器将为M
. 但是,生成器还没有做任何事情,我们只是设置了它。
该语句next(G)
实际上在M
. 因此,如果您运行next(G)
一次,您将获得第一行的总和。如果再次运行它,您将得到第二行的总和,依此类推。
>>> M = [[1,2,3],
... [4,5,6],
... [7,8,9]]
>>>
>>> G = (sum(row) for row in M) # create a generator of row sums
>>> next(G) # Run the iteration protocol
6
>>> next(G)
15
>>> next(G)
24
如果您已经走到了这一步,那么您应该已经知道常见的 for-in 语句是如何工作的。
以下声明:
for row in M: print row
将 M 视为由 3 行(子序列)组成的序列,每行包含 3 个项目,并遍历 M,输出矩阵上的每一行:
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
你知道的,嗯...
您可以将生成器视为 for-in 循环周围的一些语法糖。忘记 sum() 调用,在 IDLE 上输入类似这样的内容:
G = (row for row in M)
print G
for a in G: print a
你看,生成器不能直接表示为文本,而不仅仅是序列可以。但是,您可以像序列一样遍历生成器。
然后你会发现一些很大的不同,但基本情况是你可以使用生成器不只返回序列中每个项目的值,而是返回任何表达式的结果。在本教程的示例中,表达式为 sum(row)。
尝试以下操作,看看会发生什么:
G = ("("+str(row[2])+";"+str(row[1])+";"+str(row[0])+")" for row in M)
G.next()
G.next()
G.next()