day012生成器函数、生成器表达式、列表推导式

本节主要内容

  • 生成器和生成器表达式

  • 列表推导式

一、生成器

  • 生成器实质就是迭代器

1、python中获取生成器的三种方式:

* 通过生成器函数
* 通过生成器表达式
* 通过数据的转换获取生成器

1.生成器函数

**fe1:**
'''python
def func():
    print("111")
    yield 222
ret = func()        #generator 生成器
print(ret)  #结果:<generator object func at 0x10567ff68>
'''
  • 函数里面有yield,就是生成器函数

    * yield的作用

      ① yield + 返回值 (是一个类似 return 的关键字,迭代一次遇到yield时就返回yield后面(右边)的值。
      (生成器函数不要出现return)
      ② 重点是:下一次迭代时,从上一次迭代遇到的yield后面的代码(下一行)开始执行。(分段执行)
      ③  生成器函数被调用的时候. 返回生成器
    
      def func():
          yield
      g = func() - 得到生成器

2.生成器的用法

  **生成器的用法和迭代器基本一致**
  *  __next__() 开始执行生成器 .  执行到yield. 直到没有yield. 抛出StopIteration

  * send() 可以给上一个yield传值,send()不可以在第一个位置和最后一个位置出现

fe:

'''python
def func():
    print("水饺")
    a = yield "大馅水饺"
    print("a=", a)
    print("烧饼")
    b = yield "武大郎烧饼"
    print("b=",b)
    print("老婆饼")
    c = yield "只要老婆不要饼"
    print("c=", c)

gen = func() # 生成器
print("返回值是:", gen.__next__())
print("返回值是:",gen.send("混沌面")) #  和__next__()一样也是向下找yield. 给上一个yield传值
print("返回值是:",gen.send("胡辣汤")) #  和__next__()一样也是向下找yield. 给上一个yield传值
print("返回值是:",gen.send("马拉")) #  和__next__()一样也是向下找yield. 给上一个yield传值

 send()不可以在第一个位置和最后一个位置出现
 最后的yield后的代码是可以执行的但是会报错. StopIteration
 '''

2、生成器的三大特点(同迭代器)

 1. 省内存
 2. 惰性机制,  不访问__next__() 就没有值.
 3. 只能向前. 不能反复.

二、各种推导式(简单)

  • 列表推导式 语法: [ 结果 for循环(可多个) if判断] 就三种,其中if可有可无

  • 字典推导式 语法: { key:value for循环 if判断}

  • 集合推导式 语法: { key for循环 if判断}

  • 切记没有元组推导式,推导式指的是可以迭代的,元组不可迭代

    扫描二维码关注公众号,回复: 3885508 查看本文章

fe1:

'''python
列表推导式 快速的简单的创建一个列表
lst = ["python全栈%s期" % i for i in range(1, 17)]
语法: [结果 for循环 if判断]
'''

fe2:

'''python
成列表: 1-20 所有的奇数的2次方
print([ i*i for i in range(1,21) if i % 2 == 1])
'''

fe3:

'''python
# [3,6,9]  已知
# [(1,2,3), (4,5,6), (7,8,9)]
# lst = [3,6,9]
# new_lst = [(el-2, el-1, el) for el in lst]
'''

fe4:

'''python
寻找名字中带有两个e的⼈的名字 name.count("e") == 2
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven','Joe'],
     ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]

lst = [name for el in names for name in el if name.count("e") == 2]
print(lst)

**此处使用到了两层for循环**
'''

fe5:字典中的推导式

'''python
dic = {"张无忌":"赵敏", "杨过":"小龙女", "郭靖":"黄蓉"}
# 把字典中的key和value互换
# dic = {"赵敏":"张无忌", "小龙女":"杨过", "黄蓉":"郭靖"}
dic1 = { v:k for k, v in dic.items()}  # 强化记忆,理解
print(dic1)

dic2 = { dic[k]:k for k in dic} # 强化记忆,理解
print(dic2)

'''

fe6:集合中的推导式

'''python
集合推导式 # 不可变. 不重复, 无序
{结果 for循环 if判断}
s = {i*"胡辣汤" for i in range(10)}
print(s)
'''

三、生成器表达式

  • 生成器表达式 (结果 for循环 if判断) => 生成器表达式

1、特点: 本质是迭代器. next()

1. 省内存
2. 惰性机制
**生成器只有在访问时才取值,你找他要,他才给你值,
不找是不会执行的,面试题就喜欢出这里,**
3. 只能向前

2、实例

1、惰性机制的体现

fe1:
**list内置了for循环**
'''python
g = (i for i in range(10))
#* s = {1,2 , 3, 4, 5} => list(s) => list = [1,2,3,4,5,]
#上面的转换说明了list里面存在,for循环
print(list(g)) # 把传递进来的数据转化成列表.  里面包含了for循环
# list() => for=> __iter__() ==> __next__()

print(list(g)) # 上一次已经拿没了
print(g.__next__()) # 已经没有数据了
for el in g:
    print(el)
for el in g: # 已经没有数据了 惰性机制-> 只能往前
print(el)
'''
fe2:重要的面试题
'''python
def func(): # 生成器函数
    print(111)
    yield 222

g = func() #  生成器 -> 没有执行过__next__()
g1 = (i for i in g) # 生成器表达式. 也没有__Next__()
g2 = (i for i in g1) # 生成器表达式. 也没有__Next__()
#到此为止, 没有人拿过值

**需要知道的知识点:list里内置了for循环**

print(list(g2)) # 111 [222] #
print(list(g)) #  []
print(list(g1)) # []

**关键点:生成器表达式,一旦被拿完了,就没有了,直白说,一旦被人拿了,就没了。**
'''

3、yield from

⼩坑

yield from是将列表中的每⼀个元素返回. 所以. 
如果写两个yield from 并不会产⽣交替的效果

fe1:

'''python
def gen():
    lst = ["⿇花藤", "胡辣汤", "微星牌饼铛", "Mac牌锅铲"]
    yield from lst # 把列表中的每一个元素返回
    # yield  lst[0] # 等同于下面四个命令的组合
    # yield  lst[1]
    # yield  lst[2]
    # yield  lst[3]

g = gen() # 生成器函数 -> 获取生成器
for el in g:
    print(el)
    '''

fe2:

'''python
def gen():
lst = ["⿇花藤", "胡辣汤", "微星牌饼铛", "Mac牌锅铲"]
lst2 = ["饼铛还是微星的好", "联想不能煮鸡蛋", "微星就可以", "还可以烙饼"]
yield from lst  # 先循环打印lst,再打印lst2
# yield lst[0]
# yield lst[1]
# yield lst[2]
# yield lst[3]
yield from lst2
# yield lst2[0]
# yield lst2[1]
# yield lst2[2]
# yield lst2[3]

g = gen() # 获取生成器
for el in g: # 从生成器获取数据
    print(el) # 打印
'''

猜你喜欢

转载自www.cnblogs.com/yipianshuying/p/9891373.html