Python高级特性(生成式与生成器)

1.列表生成式
列表生成式就是一个用来生成列表的特定语法形式的表达式。是python提供的一种生成列表的简洁形式,可快速生成一个新的列表

1).普通语法格式:

[exp for iter_var in iterable]

例如:生成一个2n+1的数字列表,n为从3到11的数字

list=[2*i+1 for i in range(3,12)]

在这里插入图片描述
2).带过滤功能语法格式:

[exp for iter_var in iterable if_exp]
[exp if_exp else_exp for iter_var in iterable]     #若是if-else语句,则放在for之前

例如:找出1-100之间的所有奇数,并返回一个列表。如果能被3整除,返回该书的平方,否则返回该数的三次方。
Python高级特性(生成式与生成器)_第1张图片
3).循环嵌套语法格式

[exp for iter_var_A in iterable_A for iter_var_B in iterable_B]

例:
在这里插入图片描述
2.集合生成式
用花括号括起来
例:
在这里插入图片描述
3.字典生成式
在表达式中用键值对表示
例:
在这里插入图片描述

#######生成器Generator#######

什么是生成器?
在pyhton中,一边循环以便计算的机制,称为生成器。
什么时候需要使用生成器?
一般情况下我们不需要使用生成器,只有当我们因为性能限制才需要用到,比如我们使用python读取一个10g的文件,如果一次性将10g的文件加载到内存处理的话,内存肯定会溢出。如果使用生成器把读写交叉处理,比如使用(readline和readlines)就可以再循环读取的同时不断处理,这样就可以节省大量的内存空间。

如何创建生成器?
方法一:列表生成式的改写。[]改写为()
在这里插入图片描述
方法二:yield关键字和send函数
如果函数里面有yield关键字,这个函数的返回值就是一个生成器。
如果遇到yield,函数停止执行,当再次调用next方法,从停止的地方开始执行。
下面我们从代码例子来了解yield关键字。

def fun():
    print('step1')
    while 1:
         obj = yield 'step2'
         print('obj:',obj)
         print('step3')
         obj1 = yield 'step4'
         print('obj1:',obj)
g=fun()

print(next(g))
print('-'*10)
print(next(g))
print('-'*20)
print(next(g))

#######运行结果######
step1
step2
----------
obj: None
step3
step4
--------------------
obj1: None
step2

我们逐步分析yield关键字函数是怎么运行的:
1.程序开始执行,因为fun()中含有yield关键字,所以fun并不会真正执行,而是得到一个生成器。
2.直到调用next方法,fun函数开始执行,第一个print(next(g))语句先执行的是fun中的print(‘step1’),接着继续进入while循环,程序遇到yield关键字,返回一个step2,然后程序停止(等到再次调用next才会继续执行),所以第一个print(next(g))运行得到的结果是step1和step(运行结果前两行)。
3.程序继续执行print(’-’*10),运行结果输出10个‘-’。
4.程序再次执行下面的print(next(g)),这个时候fun函数从上一个next方法停止的地方(yield关键字)执行,也就是先执行obj赋值操作,此时是没有值赋给obj的,因为obj后面的参数在上一次执行的时候已经return出去了,所以此时obj的值为None,再接着执行print(‘step3’),再次遇到yield,返回’step4’,然后程序再次停止。在这期间程序输出obj: None,step3 ,step4
5.程序继续执行print(’-’*20),运行结果输出20个‘-’。
6.程序接着执行最后一个print(next(g)),fun函数从上一个next方法停止的地方执行,同样obj1的值为None,此时虽然已经执行到fun函数的最后一行,但由于函数中有while循环,所以程序继续执行while循环,再次遇到yiele ‘step2’,返回’step2’,程序停止。在这期间程序输出 obj1: None , step2
7.程序执行结束,直到调用下一个next方法。

同样我们用程序举例send函数的用法:

def fun():
    print('step1')
    while 1:
         obj = yield 'step2'
         print('obj:',obj)
         print('step3')
g=fun()
print(next(g))
print('-'*10)
print(g.send('pets'))


######运行结果######
step1
step2
----------
obj: pets
step3
step2

分析:
当执行print(g.send(‘pets’))时,程序从上一次中断的地方,即给obj赋值的地方开始执行,我们上面说到,yield返回一个对象,但并不会赋值给obj,那send就是发送一个参数给obj,程序开始执行,send把参数‘pets’赋值给obj,然后执行next方法,程序继续执行,打印step3,因为while循环再次碰到yield,返回‘step2’,程序停止运行。所以执行print(g.send(‘pets’))得到的结果为obj: pets,step3 ,step2
如何打印生成器的每一个元素?
1).通过for循环,依次计算并生成每一个元素
Python高级特性(生成式与生成器)_第2张图片
2).如果要一个一个打印,通过next()函数获得生成器的下一个返回值
Python高级特性(生成式与生成器)_第3张图片

你可能感兴趣的:(python)