生成器和生成器表达式

一. 生成器.

  生成器的本质就是迭代器.

  在python中有三种方式来获取生成器:

    1. 通过生成器函数.

    2. 通过各种推导式来实现生成器.

    3. 通过数据的转换也可以获取生成器.

  特点: 1. 节省内存

      2. 惰性机制

      3. 只能向前

二. 生成器函数.

  这是一个简单的函数

def func():
    print("111")
    return 222
ret = func()
print(ret)
结果: 
111
222
View Code

  将函数中的return换成yield就是生成器

def func():
    print("111")
    yield 222

ret = func()
print(ret)

结果: 
<generator object func at 0x10567ff68>
View Code

  1. gen = func()  函数并不会被执行, 而事故创建一个生成器对象

def func():
    print("111")
    yield 222

gener = func() # 这个时候函数不会执行. 而是获取到生成器
ret = gener.__next__() # 这个时候函数才会执行. yield的作用和return一样. 也是返回数据
print(ret)
结果: 
111
222
View Code

  2. send和__next__()的区别:

    1. send和__next__()都是让生成器向下走一次

    2. send可以给上一个yield的位置传递值, 不能给最后一个yield发送值, 在第一次执行生成器

    代码的时候不能使用send().

def generator():
    print(123)
    content = yield 1
    print('=======',content)
    print(456)
    yield2

g = generator()
ret = g.__next__()
print('***',ret)
ret = g.send('hello')   #send的效果和next一样
print('***',ret)

#send 获取下一个值的效果和next基本一致
#只是在获取下一个值的时候,给上一yield的位置传递一个数据
#使用send的注意事项
    # 第一次使用生成器的时候 是用next获取下一个值
    # 最后一个yield不能接受外部的值
View Code

三. 列表推导式, 生成器表达式以及其他推导式.

  1. 列表推导式是通过一行来构建你要的列表, 列表推导式看起来代码简单, 但是出现错误之后很难排查.

    列表推导式的常用写法:

    [结果 for 变量 in 可迭代对象]

  例. 从python1期到python14期写入列表lst:

lst = ['python%s' % i for i in range(1,15)]
print(lst)
View Code

  2. 生成器表达式和列表推导式的语法基本是一样的, 只是把[]换成().

  3. 生成器表达式和列表推导式的区别:

    1. 列表推导式比较耗内存, 一次性记载, 生成器表达式几乎不占用内存, 使用的时候才分配和使用内存.

    2. 得到的值不一样, 列表推导式得到的是一个列表, 生成器表达式获取的是一个生成器.

  4. 字典推导式: 推导出来的是字典

# 把字典中的key和value互换
dic = {'a': 1, 'b': '2'}
new_dic = {dic[key]: key for key in dic}
print(new_dic)

# 在以下list中. 从lst1中获取的数据和lst2中相对应的位置的数据组成一个新字典
lst1 = ['jay', 'jj', 'sylar']
lst2 = ['周杰伦', '林俊杰', '邱彦涛']
dic = {lst1[i]: lst2[i] for i in range(len(lst1))}
print(dic)
View Code

  5. 集合推导式可以帮我们直接生成一个集合, 集合的特点: 无序, 不重复, 所以集合推导式自带去重功能.

  总结: 推导式有列表推导式, 字典推导式, 集合推导式. 没有元组推导式.

      生成器表达式: (结果 for 变量 in 可迭代对象 if条件筛选)

      生成器表达式可以直接获取到生成器对象, 生成器对象可以直接进行for循环.

  最后给大家一个面试题, 难度系数很高.

def add(a, b):
    return a + b

def test():
    for r_i in range(4):
    yield r_i

g = test() 
for n in [2, 10]:
    g = (add(n, i) for i in g)

print(list(g))

提示: 惰性机制, 不到最后不拿值.

  

 

  

posted on 2018-09-18 15:16  噬心人  阅读(142)  评论(0编辑  收藏  举报