# list expression
= [1, 2, 3]
L = [i**2 for i in L]
x print(x)
[1, 4, 9]
Tom
September 11, 2024
生成器表达式(generator expression)是 Python 中的一种简洁方式,用来在迭代时生成数据,而不是一次性将所有结果存储在内存中。它与列表推导式(list comprehension)类似,但它不返回整个列表,而是返回一个生成器对象,通过惰性求值节省内存。
列表推导式可以快速从一个可迭代对象生成一个新的列表。比如我们从 L 生成一个新的列表 x:
生成器表达式则返回一个生成器对象,可以通过 next()
函数计算求值:
<generator object <genexpr> at 0x7f3276ef7440>
1
next()
函数会记录上一次打印的值从上一次中断处继续执行,直到循环结束抛出异常:
4
9
--------------------------------------------------------------------------- StopIteration Traceback (most recent call last) Cell In[4], line 3 1 print(next(x)) 2 print(next(x)) ----> 3 print(next(x)) StopIteration:
以上当 3 次求值再进行求值便抛出异常。同理也可以使用 for 循环对生成器表达式进行迭代:
在 Python 中,迭代器(Iterator)是一种用于遍历元素的对象,允许你逐个访问容器(如列表、元组、字典、集合等)中的元素,而无需关心容器的底层实现。Python 中迭代器必须实现两个方法:__iter__()
和 __next__()
。
__iter__()
:返回迭代器对象本身。这个方法使对象可以被 iter()
函数调用。__next__()
:返回容器的下一个元素。当没有元素时,会引发 StopIteration
异常来结束迭代。迭代器不会在内存中一次性生成所有元素,而是在每次调用 next()
方法是生成下一个值。且迭代器只能遍历一次,一旦迭代完毕就会耗尽,不能再次使用。
生成器是一种特殊的迭代器。生成器通过使用 yield
关键字定义,与普通函数不同的是,生成器函数在执行时会保存它的状态(局部变量、位置等),每次调用时可以从上次停止的地方继续执行。这种特性使得生成器非常适合处理大量数据或无限序列,因为它可以按需产生值,而不需要一次性将所有数据加载到内存中。
# 定义生成器
def generator_test():
for i in [1, 2, 3]:
yield i
# 使用生成器
gen = generator_test()
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
1
2
3
--------------------------------------------------------------------------- StopIteration Traceback (most recent call last) Cell In[6], line 11 9 print(next(gen)) 10 print(next(gen)) ---> 11 print(next(gen)) StopIteration:
在上面的代码中,我们定义了一个生成器函数,它在每次执行到 yield
时返回一个值并暂停执行,直到被再次调用。通过 next()
逐步求值。迭代 3 次完毕后再次求值抛出异常。
Python 也提供了一些内建的生成器函数,可以简化某些常见的迭代任务,并节约内存空间,比如 range()
、enumerate()
、zip()
等。
在 Python 中,可迭代对象(Iterable)是指可以逐个返回其元素的对象。可迭代对象实现了 __iter__()
方法,允许你使用 for 循环或其他迭代方式遍历其元素。常见的可迭代对象包括列表、元组、字符串、字典、集合等。
我们可以使用 Python 标准库中的 collections.abc.Iterable
来检查对象是否是可迭代的:
from collections.abc import Iterable
print(isinstance([1, 2, 3, 4], Iterable))
print(isinstance(1234, Iterable))
True
False
可迭代对象可以被 iter()
函数转化为迭代器:
事实上,当我们使用 for 循环或其他迭代操作时,Python 会在后台调用 iter()
函数将可迭代对象转化为迭代器,然后使用 next()
函数逐个获取元素,直到捕获 StopIteration
异常,但不会抛出该异常。