【发布时间】:2020-02-04 00:03:54
【问题描述】:
我来自 Matlab 背景,我发现很难绕过 Python 中生成器的概念。
谁能回答我以下问题:
- 生成器函数和循环之间的区别
- 何时实施
【问题讨论】:
标签: python loops iterator generator
我来自 Matlab 背景,我发现很难绕过 Python 中生成器的概念。
谁能回答我以下问题:
【问题讨论】:
标签: python loops iterator generator
阅读以下文章How to Use Generators and yield in Python。也许下面的例子有助于理解概念。
def my_range(n):
for i in range(n):
yield i
range_of_10 = my_range(10)
for i in range_of_ten:
print(i)
结果:
0
1
3
4
5
6
7
8
9
或
>>> range_of_ten = my_range(10)
>>> next(range_of_ten)
0
>>> next(range_of_ten)
1
etc.
>>> next(range_of_ten)
9
>>> next(range_of_ten)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
我喜欢下面的例子,你可以在一个循环中替换一个双循环,如下所示:
def double_loop(n, m):
for i in range(n):
for j in range(m):
yield i, j
n = double_loop(2, 4)
for i in n:
print(i)
结果
(0, 0)
(0, 1)
(0, 2)
(0, 3)
(1, 0)
(1, 1)
(1, 2)
(1, 3)
【讨论】:
生成器提供了一种“动态”创建元素的方法,而无需在我们开始遍历它们之前将它们全部保存在内存中。循环只是一种使生成器或另一个可迭代对象一次给我们一个元素的方法。
例如:
for i in range(10):
print(i)
for 块是一个循环,range 基本上是一个生成器。 range 不会在循环开始之前从 1-10 创建 list,它只是创建生成器,即这些元素的创建者。您还可以想象range(1000000000000000000),它也不需要任何时间来创建(并且不会占用内存),因为在需要它们之前不会创建任何元素。
另一方面,我们的循环也可以从已经存在的对象中获取一个元素,例如list:
for i in [0,1,2,3,4,5,6,7,8,9]:
print(i)
将打印相同的结果,但列表是在循环开始之前创建并存储在其条目中的。这意味着在循环运行时,列表会占用内存空间和时间来创建。
这两个例子都是循环,但只有第一个使用了生成器。
这只是基础,但还有更多区别,例如可以引发的异常和可重用性、部分迭代等等。
有关difference的更多信息
编辑:@Vicrobot 说 range 并不是真正的生成器是正确的,但为了解释生成器的“懒惰”,这就是我为了简单起见而使用的
【讨论】:
1:1000 在 for 循环中的工作方式与 Python 的 range 一样。也就是说,MATLAB 的for 就像这里描述的两种模式一样工作。