day11-12-迭代器和生成器

一丶函数的名的应用(第一类对象)

迭代器

    函数名的命名规范和变量是一样的

  1.函数名的运用

      函数名是一个特殊的变量,与括号搭配可以调用函数

      1.函数名的内存地址

      图片 1

      2.函数名可以赋值给其他变量

      图片 2

      3.函数名可以当做容器类的元素

      图片 3

      4.函数名可以当做函数的参数

      图片 4

      5.函数名可以作为函数的返回值

      图片 5

  1.可以做列表中的元素进行存储

def func1():
    pass
def func2():
    pass
lst = [func1, func2]
for el in lst:
    el()

  2.闭包

    闭包:内层函数对外层函数变量的引用

    

1 def func1():    2 name = "alex"    3     def func2():        4         print     # 闭包    5     func2() 6 func1() 7 结果: alex    

    我们可以使用__closure__来检测函数是否是闭包.
使⽤用函数名.__closure__返回cell就是闭包. 返回None就不是闭包.
    在函数外边调用内部函数,只需使用return返回即可。

     闭包的好处:使用闭包,可以保证外层函数的变量在内存中常驻,供后面的程序使用。

  2.可以作为参数传递给函数.

def func():
    pass
def proxy(fn):
    fn()
proxy(func)

 

  3.迭代器

    查看是否为可迭代对象,第一种办法,使用dir判断是否有__iter__()。

    图片 6

      如果对象中有__iter__函数.
那么我们认为这个对象遵守了可迭代协议. 就可以获取到相应的迭代器.
这⾥的__iter__是帮助我们获取到对象的迭代器. 我们使⽤迭代
器中的__next__()来获取到⼀一个迭代器中的元素.

      图片 7

      使用while循环+迭代器来模拟for循环

      图片 8

      总结:

      lterable:可迭代对象,内部包含__iter__()含糊

      lterator:迭代器。内部包含__iter()__同时包含__next__()

      迭代器的特点:

        1.节省内存

        2.惰性机制

        3.不能反复,只能向下执行

      我们可以把迭代的内容想象成子弹,获取到迭代器__iter__().当成把子弹装到弹夹中。然后发射就是__next__()把每一个子弹打出来。也就是说,
for循环的时候. ⼀开始的 时候是__iter__()来获取迭代器.
后⾯每次获取元素都是通过__next__()来完成的. 当程序遇到
StopIteration将结束循环.

  3.可以作为函数的返回值

def func():
    def inner():
        pass
    return inner
func()()

生成器和表达式

  4.函数名的内存地址

def func():
    print("呵呵")
print(func)

结果为:
<function func at 0x0000022951B03E18>

  1.生成器

      生成器实质就是迭代器。

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

      1.通过生成器函数

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

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

      图片 9

      图片 10

      如果函数中存在了yield,那么这个函数就是个生成器函数。这个时候,我们在执行这个函数,就是在获取这个生成器了。

      图片 11

      注意:当程序运行完最后一个yield后,那么后面继续进行__next__()程序则会报错。

      send方法,
send和__next__()一样都可以让生成器执⾏到下⼀个yield。     

      send和__next__()区别:

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

        2. send可以给上⼀个yield的位置传递值,
不能给后一个yield发送值. 在第⼀次执行⽣成器代码的时候不能⽤用send()

      生成器可以用for循环来获取内部元素。

      图片 12

二丶闭包

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

      列表推导式:通过一行来构建你要的列表,

lst = [i for i in range]

      还可以对数据进行筛选:

      图片 13

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

      图片 14

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

        1.列表推导式比较耗内存,一次性加载。生成器表达式基本上不占内存,使用的时候分配和使用内存

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

        注意:生成器的惰性机制,只有在访问的时候取值。

        图片 15

      字典推导式:

图片 16

      集合推导式:生成一个集合。

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

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

        生成器表达式可以直接获取到生成器对象.
生成器对象可以直接进行for循环. ⽣成器具有惰性机制.

    闭包:在内层函数中访问外层函数的局部变量

    好处:

      1.保护变量不受外界影响

      2.可以让变量常驻内存

    写法:

def outer():
    a = 10
    def inner():
        print(a)
    return inner

 

    如何判断是不是闭包,可以用__closure__来检测函数是否是闭包,使用函数名__closure__返回cell就是闭包,返回None就不是闭包

def func1():
    name = "alex"
    def func2():
        print(name)
    func2()
    print(func2.__closure__) #(<cell at 0x0000023BA6A6B498: str object at 0x0000023BA6AFA7A0>,)
func1()

 

 

三丶迭代器

    用来遍历列表,字符串,元组……..可迭代对象

#对的
s = "abc"
for c in s:
    print(c)

#错的
for i in 123:
    print(i)