Title

函数三大器之生成器

生成器(generator)

1.什么是生成器?

生成的工具。生成器是一个 "自定义" 的迭代器, 本质上是一个迭代器。

2.如何实现生成器

但凡在函数内部定义了的yield,调用函数时,函数体代码不会执行,会返回一个结果,该结果就是一个生成器。

yield: 每一次yield都会往生成器对象中添加一个值。

注意:

  • yield只能在函数内部定义

  • yield可以保存函数的暂停状态

def func():  # 定义一个函数
   print('from func')
   yield 'tank'   # 定义yield,需要添加什么值就在后面直接添加
res = func()
print(res)      # 打印的结果就是一个生成器,并且直接打印是不会执行函数体代码的
def func():
   print('from func')
   yield {'tank':'sean'}  # yield后面可以添加多个类型的值,如果是多个字符串,返回的是元组,如果以字典的形式添加返回的是字典

res = func()
print(res.__next__())   # 只有以res.__next__()或者next(res)的形式才会执行函数体代码并将添加的值取出来
def func():
   print('开始准备下蛋')
   print('1---火鸡蛋1')
   yield '火鸡蛋1'     # 每一次yield就往生成器里面添加一次值
   print('2---火鸡蛋2')
   yield '火鸡蛋2'
   print('3---火鸡蛋3')
   yield '火鸡蛋3'

   print('取最后一个蛋,查看是否有')

res = func()
print(next(func()))          # 只会取第一次添加的值
print(next(func()))
print(next(func()))
                # 上下两种情况是不一样的
# print(next(res))           # 会一个一个将添加的值取出来
# print(next(res))
# print(next(res))
def func():        # 循环yield添加值
   n = 0
   print('开始准备下蛋')
   while n < 4:
       print(f'1---火鸡蛋{n}')
       yield f'火鸡蛋{n}'
       n += 1

res = func()
while True:      # 循环取值
   try:         # 注意,只有取出来上面的函数体才会正常运行
       print(next(res))
   except StopIteration:
       break

yield与return比较:

相同点:返回值的个数都是无限制的。

不同点: return只能返回一次值,yield可以多次使用返回多个值

3.for循环里面的range

注意:在python2中,for 循环里面的range(1,5)----->得到的是列表[1, 2, 3, 4]

在python3中,for循环里面range(1,5)---->得到的是一个生成器,本质上就是一个迭代器

# 自定义range功能,创建一个自定义的生成器
# (1, 3) # start--> 1 , end---> 5, move=2
def my_range(start, end, move=1):  #
   while start < end:
       yield start
       start += move

g_range = my_range(1, 5)
print(g_range)    # 本质是一个生成器
print(next(g_range))
输出结果:
<generator object my_range at 0x00000289B10A8348>
1


for line in g_range:
   print(line)
输出结果:
   1
   2
   3
   4


for line in my_range(1, 5, 2):
   print(line)
输出结果:
   1
   3
   

列表生成式

1.什么是列表生成式?

可以一行代码实现列表

语法:

list = [取出的每一个值、任意值 for 可迭代对象中取出的每一个值 in 可迭代对象]

注意:

for的右边是循环次数,并且可以取出可迭代对象中每一个值

for的左边可以为当前列表添加值

list = [for 可迭代对象中取出的每一个值 in 可迭代对象]        

list = [for 可迭代对象中取出的每一个值 in 可迭代对象 if 判断]
一般情况:
l1 = []  # 先定义一个空集合
l2 = [1, 2, 3, 4,]
def func():
   for i in l2:
       l1.append(i)  # 逐个添加元素
   print(l1)
func()


列表生成式
l1 = [1, 2, 3, 4, 5]
l2 = [i for i in l1]

l2 = [i for i in range(1,6)]
print(l2)


将name_list列表中的jason过滤掉,其他人后缀都添加_dsb
name_list = ['jason', '饼哥(大脸)', 'sean', 'egon', 'tank']
new_name_list = [name + '_dsb' for name in name_list if not name == 'jason'] # 可以添加if进行判断


print(new_name_list)

 

2.生成器表达式和列表生成器对比

生成器表达式(生成器生成式):   
   - 列表生成式:  若数据量小时采用        
[line for line in range(1, 6)] ---> [1, 2, 3, 4, 5]        
优点:  可以依赖于索引取值,取值方便      
缺点:  浪费资源    
   - 生成器生成式:  若数据量过大时采用
() ---> 返回生成器    
(line for line in range(1, 6)) ---> g生成器(1, 2, 3, 4, 5)        
优点:  节省资源        
缺点:  取值不方便
 

# 生成一个有1000个值的生成器
g = (line for line in range(1, 1000001))  
# <generator object <genexpr> at 0x00000203262318E0>print(g)
# 列表生成式实现
list1 = [line for line in range(1, 1000001)]
print(list1)

三元表达式

1.什么是三元表达式?

三元表达式就是将if...else...分支变成一行代码

语法:

条件成立返回左边的值 if 判断条件 else 条件不成立返回右边的值

举例:
   def func(a, b):
   if a > b :
       return a
   else:
       return b

print(func(3,5))

# 写成三元表达式形式

def func(a,b):
   res = a if a > b else b
   print(res)

func(5,3)

 

posted @ 2019-11-14 21:35  Mr江  阅读(453)  评论(0编辑  收藏  举报