13.Generator And Yield
and 13 Generator yield
2023-09-27 14:26:28 时间
欢迎访问个人网络日志🌹🌹知行空间🌹🌹
1.生成器Generator
在2001创建的PEP255中引入的,生成器函数是返回懒加载迭代器的函数,使用上像list
,但与list
不同的时,生成器中保存的不是元素的值而是生成元素的逻辑关系,所以使用生成器能够节省内存。
使用生成器的几个例子:
- 读取大文件:
csv_gen = csv_reader("some_csv.txt")
row_count = 0
for row in csv_gen:
row_count += 1
print(f"Row count is {row_count}")
通过普通的方式定义csv_reader
函数时会因为读取的文件过大导致内存耗尽:
def csv_reader(file_name):
file = open(file_name)
result = file.read().split("\n")
return result
因为要把csv
文件的每行都读取到result
中,内存不够时将会导致报错:
Traceback (most recent call last):
File "ex1_naive.py", line 22, in <module>
main()
File "ex1_naive.py", line 13, in main
csv_gen = csv_reader("file.txt")
File "ex1_naive.py", line 6, in csv_reader
result = file.read().split("\n")
MemoryError
通过使用生成器,能够避免这种问题,定义csv_reader
函数如下:
def csv_reader(file_name):
for row in open(file_name, "r"):
yield row
生成器中会保留读取的文件句柄,不会重复的open
文件,又不会加载文件中的内容,因此需要的内存也比较少。
- 生成一个无穷序列
def infinite_sequence():
num = 0
while True:
yield num
num += 1
gen = infinite_sequence()
for i in range(3):
print(next(gen))
# 0
# 1
# 2
- 生成器表达式
通过圆括号表达式生成生成器。
import sys
nums_squared_lc = [num**2 for num in range(100)]
print(sys.getsizeof(nums_squared_lc))
# 920
nums_squared_gc = (num**2 for num in range(100))
print(sys.getsizeof(nums_squared_gc))
# 112
可以看到生成器所需要的内存比普通迭代器容器需要的少的多。
2.yield
语句
yield
语句用于生成器函数中,其功能有些类似于普通函数中的return
语句,主要用来控制生成器函数的逻辑流。
图片来自于2
使用yield
语句的函数返回的是一个生成器,当每次使用next
的函数去获取生成器中的值时,每次生成器函数都会执行到yield
的语句,只到再次迭代或next
生成器。
当执行到yield
语句时,函数返回yield
的值,并将函数的状态挂起,会将生成器函数相关的任何局部变量保存起来,包括指针,函数的栈,和异常,如前面读取文件的上下文句柄。
参考资料
相关文章
- Design Challenges and Misconceptions in Neural Sequence Labeling 论文阅读
- [OpenCV] Samples 15: Background Subtraction and Gaussian mixture models
- Autodesk View and Data API练练手
- Struts2中关于"There is no Action mapped for namespace / and action name"的总结
- JDK 8 and JRE 8 Supported Locales
- Comparing files, folders and text sources
- sourcemaps and persistent modification in chrome
- Nginx rewrite URL examples with and without redirect address
- Installed Build Tools revision 31.0.0 is corrupted. Remove and install again using the SDK Manager.
- Apache Kudu as a More Flexible And Reliable Kafka-style Queue
- The Reflection And Amplification Attacks && NTP Reply Flood Attack Based On NTP
- STM32 USB FS Core and USB OTG Core
- Authentication and Integration 第三篇:Oracle LDAP介绍
- (转)YV12 and NV12