闭包,迭代器,生成器,列表推导式

1:函数名的应用

      1, 函数名就是函数的内存地址。
    2, 函数名可以作为变量。
    3, 函数名可以作为函数的参数。
    4, 函数名可以作为容器类类型的元素。
    5,函数名可以当做函数的返回值。

2:globals() locals()

  globals() # 返回全局变量的一个字典。

  locals()  返回 当前位置 的局部变量的字典。

  

 1 name = 'leiwenxuan'
 2 def fun():
 3     a = 2
 4     b = 3
 5 
 6     print(globals()) #返回的是全局变量的字典修改其中的值,name 会发生变化
 7     globals()['name'] = 'wuyan'
 8     print(name)  #此时name = wuyan
 9     locals()['a'] = 5
10     print(locals()) #输出还是此时{'b': 3, 'a': 2}
11 fun()

3:闭包

  定义:内层函数对外层函数变量的引用(非全局)并且外层函数返回内层函数的函数名,形成闭包

    

def func():
    name1 = 'leiwenxuan'
    def inner():
        print(name1)
    return inner
f = func() #形成闭包
f()  

   闭包的作用:当程序执行时,遇到了函数执行,他会在内存中开辟一个空间,局部名称空间, 如果这个函数内部形成了闭包,  那么他就不会随着函数的结束而消失。

4:可迭代对象

  对象内部对象内部含有__iter__方法就是可迭代对象.可迭代对象满足可迭代协议。

  可迭代对象:str list dict,tuple,set,range()

    1 #print('__iter__' in dir(s1)) 2 #print('__iter__' in dir(dic)) 

    

1 from collections import Iterable
2 from collections import Iterator
3 
4 print(isinstance('leiwenxuan', Iterator)) #False
5 
6 print(isinstance('leiwenxuan', Iterable)) #True

5: 对象内部含有__iter__方法且含有__next__方法就是迭代器.

  1;可迭代对象vs迭代器:  

       可迭代对象不能取值,迭代器是可以取值的。
       可迭代对象 --->(转化成)迭代器

  2:可迭代对象转化迭代器: 

    iter1 = iter(lis)

    iter2 = lis__iter()__

  3:可迭代对象取值,

    next() 一次取一次

    iter.__next__()

  4:可迭代对象的好处

    1, 可迭代对象不能取值,迭代器是可以取值的。
    2, 迭代器非常节省内存。
    3,迭代器每次只会取一个值。

    4,迭代器单向的,一条路走到头

  5:自己实现for循环

    1,将可迭代对象转化成迭代器。
     2,调用__next__方法取值。
     3,利用异常处理停止报错。
     iter1 = s1.__iter__()

    

1 while 1:
2      try:
3          print(iter1.__next__())
4      except StopIteration:
5         break

6:生成器:就是自己用python写的迭代器,生产器的本质就是迭代器

    用以下两种方式构建生成器
  • 通过生成器
  • 生成器表达式
  • 函数
    def fun():
        x += 1
        return x
    fun() #函数的执行命名,并接受函数返回值
     
    def fun1():
        x += 1
        yield x
    g = fun1()  #生成器函数对象
    g.__next__() #调用 
     
    #一个next对应一个 yield
    #yield 将返回给生成器对象__next__()
     
return and yield
return 结束函数, 给函数执行者返回值
yield 不会结束函数, 一个next对象一个yield给生成器对象__.next__()返回值
 
区别:
    1:内存级别的区别
    2:迭代器是需要可迭代对象转化, 可迭代对象是非常占内存的
    3:生成器直接创建, 不需要转化, 从本质就节省内存。
 
 
send 与 yield 
def fun():
    print(1)
    yield 1
    print(2)
    yield 2
g = fun()
g.send('alex')
#send 与 next 一样, 也是对生成器取值(执行一个yield)的方法
#send 可以给上一个yield传值
#第一次永远都是next
#最后一个yield永远也得不到send传的值
 
 
列表推到式:一行代码搞定你需要的任何列表
#循环模式 [变量 (加工后的变量) for ]
lis = [i for i in range(1,101)]
#筛选模式[变量 (加工后的变量) for i in name if 条件]
列表推导式:
    优点:一行解决 , 方便
    缺点:容易着迷, 不易排错, 不超过太刻意用
#列表推到式不能解决所有列表的问题,不要刻意去用
 
生成器表达式:将列表推到式的[] 换成()即可。
G = (i for i in range(1,10000000000000))
每次只取一个值

  

    

猜你喜欢

转载自www.cnblogs.com/leiwenxuan/p/9507892.html