Python 列表上的生成器与链接生成器和内存消耗?
有人能解释一下这些例子中的生成器是如何工作的吗 在本例中,来自Python 列表上的生成器与链接生成器和内存消耗?,python,generator,Python,Generator,有人能解释一下这些例子中的生成器是如何工作的吗 在本例中,来自 当我们像这样链接生成器时,在执行sum()之前,除了代码对象创建之外,还会发生任何实际工作吗 为什么我们需要执行line.split(无,1)[1] 和int(x)分开-这样做有好处吗 在本例中(x*x表示范围内的x(1100000000)) 在Python 2中,当解释器对该表达式求值时,是否计算了范围(1100000000) 这是在该语句期间还是在生成器的第一次运行期间发生的 这在Python3中有什么不同吗 我产生这种怀疑的原
def foo():
for each in range(1,100000):
yield each
a = foo()
# Here range is not evaluated until generator is run or just
# before first yield is hit which is expected.
a=(x for x in range(1,100000))
# I thought also does exact thing as that function and it i is a
# syntactic sugar for a=foo() which also yields a generator object.
与列表或场景相比,使用生成器有什么优势吗?在列表或场景中,这样做更为实际。1.当我们像这样链接生成器时,在执行sum()之前,是否会发生任何实际工作 生成器表达式返回按需生成结果的对象,而不是生成 结果列表,所以您的答案是否定的(但这仍然取决于您对实际工作的平均值) 2.为什么我们需要分别执行
line.split(None,1)[1]
和int(x)
——这样做有好处吗
它只是使您的代码更具可读性并增加灵活性(基于您对该表达式的操作),您可以在一行中完成:
在本例中(x*x表示范围内的x(1100000000))
3.Python 2中是否计算了范围(1100000000)
是的,在Python2中可以使用返回迭代器的xrange
4.如果是,是在本声明期间还是在发电机首次运行期间
5.这与Python 3中的不同吗
在Python3中,许多内置函数返回一个迭代器,如open
或range
对于您的第四个问题和您在评论中的问题,我认为这部分内容可能会有所帮助:
生成器表达式:迭代器满足理解
在Python的所有最新版本中,迭代器和列表理解的概念都是
结合了语言的一个新特性,生成器表达式。从句法上说,gen-
运算符表达式与普通的列表理解类似,但它们包含在
用括号代替方括号:
>>> [x ** 2 for x in range(4)]
[0, 1, 4, 9] # List comprehension: build a list
>>> (x ** 2 for x in range(4))
<generator object at 0x011DC648> # Generator expression: make an iterable
列表理解等值
但是,在操作上,生成器表达式与构建表达式非常不同
在内存中的结果列表中,它们返回一个生成器对象,该对象反过来支持
迭代协议,在任何迭代上下文中一次生成一个结果列表:
>>> G = (x ** 2 for x in range(4))
>>> next(G)
0
>>> next(G)
1
>>> next(G)
4
>>> next(G)
9
>>> next(G)
Traceback (most recent call last):
...more text omitted...
StopIteration
我们通常不会在生成器的引擎盖下看到下一个迭代器-
按此键是因为for循环会自动为我们触发它:
>>> for num in (x ** 2 for x in range(4)):
...
print('%s, %s' % (num, num / 2.0))
...
0, 0.0
1, 0.5
4, 2.0
9, 4.5
正如我们已经了解到的,每个迭代上下文都会这样做,包括sum、map和
已排序的内置函数;列表理解;以及我们学习的其他迭代上下文
关于第14章中的,如any、all和list内置函数。
请注意,在生成器表达式周围不需要括号(如果有)
包含在其他括号中的唯一项,如函数调用的项。额外津贴-
但是,在第二次调用排序时需要这些:
>>> sum(x ** 2 for x in range(4))
14
>>> sorted(x ** 2 for x in range(4))
[0, 1, 4, 9]
>>> sorted((x ** 2 for x in range(4)), reverse=True)
[9, 4, 1, 0]
>>> import math
>>> list( map(math.sqrt, (x ** 2 for x in range(4))) )
[0.0, 1.0, 2.0, 3.0]
生成器表达式主要是一种内存空间优化,它们不会重复-
要求同时构建整个结果列表,如方括号中的列表
理解才是。它们在实践中也可能运行得稍慢,因此它们可能是
最好仅用于非常大的结果集。关于per的更权威的声明-
不过,性能将不得不等待我们在本章后面编写的计时脚本。1.当我们像这样链接生成器时,在我们执行sum()之前,是否会发生任何实际的工作 生成器表达式返回按需生成结果的对象,而不是生成 结果列表,所以您的答案是否定的(但这仍然取决于您对实际工作的平均值) 2.为什么我们需要分别执行
line.split(None,1)[1]
和int(x)
——这样做有好处吗
它只是使您的代码更具可读性并增加灵活性(基于您对该表达式的操作),您可以在一行中完成:
在本例中(x*x表示范围内的x(1100000000))
3.Python 2中是否计算了范围(1100000000)
是的,在Python2中可以使用返回迭代器的xrange
4.如果是,是在本声明期间还是在发电机首次运行期间
5.这与Python 3中的不同吗
在Python3中,许多内置函数返回一个迭代器,如open
或range
对于您的第四个问题和您在评论中的问题,我认为这部分内容可能会有所帮助:
生成器表达式:迭代器满足理解
在Python的所有最新版本中,迭代器和列表理解的概念都是
结合了语言的一个新特性,生成器表达式。从句法上说,gen-
运算符表达式与普通的列表理解类似,但它们包含在
用括号代替方括号:
>>> [x ** 2 for x in range(4)]
[0, 1, 4, 9] # List comprehension: build a list
>>> (x ** 2 for x in range(4))
<generator object at 0x011DC648> # Generator expression: make an iterable
列表理解等值
但是,在操作上,生成器表达式与构建表达式非常不同
在内存中的结果列表中,它们返回一个生成器对象,该对象反过来支持
迭代协议,在任何迭代上下文中一次生成一个结果列表:
>>> G = (x ** 2 for x in range(4))
>>> next(G)
0
>>> next(G)
1
>>> next(G)
4
>>> next(G)
9
>>> next(G)
Traceback (most recent call last):
...more text omitted...
StopIteration
我们通常不会在生成器的引擎盖下看到下一个迭代器-
按此键是因为for循环会自动为我们触发它:
>>> for num in (x ** 2 for x in range(4)):
...
print('%s, %s' % (num, num / 2.0))
...
0, 0.0
1, 0.5
4, 2.0
9, 4.5
正如我们已经了解到的,每个迭代上下文都会这样做,包括sum、map和
已排序的内置函数;列表理解;以及我们学习的其他迭代上下文
关于第14章,比如任何,所有,