匿名函数_ 生成器

一、匿名函数

In [1]: def fn():
   ...:     pass
   ...: 

In [2]:

1、匿名函数 就是没有名字的函数,那么就用 lambda 这个关键字来定义

In [1]: lambda x: x + 1      # lambda 后面有一个参数x, 然后定义一个函数体, 冒号不换行 
Out[1]: <function __main__.<lambda>>

In [2]: def fn(x):
   ...:     return x + 1
   ...: 

In [3]: (lambda x: x + 1)(3) # lambda x: x + 1 定义函数
Out[3]: 4

In [4]: fn(3)
Out[4]: 4

In [5]: 

匿名函数的几个特点:

  • 用lambda 关键字来定义
  • 参数列表 不需要用 圆括号括起来
  • 冒号 不是用来开启新的语句
  • 最后一个表达式 没有return语句,最后一个表达式的值 就是我们的返回值

In [5]: f = fn(3)

In [6]: f
Out[6]: 4

In [7]: def counter():
   ...:     c = 0
   ...:     def inc():
   ...:         nonlocal c
   ...:         c += 1
   ...:         return c
   ...:     return inc
   ...: 

In [8]: f = counter()

In [9]: f
Out[9]: <function __main__.counter.<locals>.inc>

In [10]: f()
Out[10]: 1

In [11]: counter()()
Out[11]: 1

In [12]: f = lambda x: x + 1

In [13]: f
Out[13]: <function __main__.<lambda>>

In [14]: f(3)
Out[14]: 4

In [15]: f = fn

In [16]: f(3)
Out[16]: 4

f = lambda x: if x < 0 : # 匿名函数只能写在一行里,因为只能写在一行里,所以 python中的匿名函数又称为 单行函数
    0
    else:
        x
File "<ipython-input-35-dd0364e6568e>", line 1
    f = lambda x: if x < 0 : # 匿名函数只能写在一行里,因为只能写在一行里,所以 python中的匿名函数又称为 单行函数
                   ^
SyntaxError: invalid syntax
In [17]: def fn(x, y):     
    ...:     return x + y
    ...: 

In [18]: fn(3, 5)
Out[18]: 8

In [19]: (lambda x,y: x + y)(3, 5)  # 多个 参数
Out[19]: 8

In [20]: def fn(x, y=3):            # 默认 参数 
    ...:     return x + y
    ...: 

In [21]: fn(3)
Out[21]: 6

In [22]: (lambda x,y=3: x + y)(3)    # 默认 参数
Out[22]: 6

In [23]: 

In [23]: def fn(*args):  
    ...:     print(args)
    ...:     

In [24]: fn(*range(3))
(0, 1, 2)

In [25]: (lambda *args: print(args))(*range(3))   # 可变参数
(0, 1, 2)

In [26]: 
     
In [26]: def fn(*args, **kwargs):
    ...:     print(args)
    ...:     print(kwargs)
    ...:     

In [27]: (1, 2, 3)
Out[27]: (1, 2, 3)

In [28]: {'1': 1, '2': 2, '3': 3}
Out[28]: {'1': 1, '2': 2, '3': 3}

In [29]: {str(x): x for x in range(1, 4)} == {'1':1, '2': 2, '3': 3}
Out[29]: True

In [30]: d = {'1': 1, '2': 2, '3': 3}

In [31]: fn(**d)
()
{'1': 1, '2': 2, '3': 3}

In [33]: (lambda *args, **kwargs: print(args, kwargs))(*range(1, 4), **{str(x): x for x in range(1, 4)})   # 可变参数+参数解构+字典解析
(1, 2, 3) {'1': 1, '2': 2, '3': 3}   # 可变参数+参数解构+字典解析

In [34]: (lambda **kwargs: print(kwargs))(a=1)
{'a': 1}

In [35]:  


  • int 类型 不能作为 关键字参数
  • 可变关键字参数, 需要使用 字典 传入
  • 参数解构 是需要 有两个星号**, 而不是传入字典
In [35]: (lambda *, x: print(x))(x=3)  # keyeord-only 参数
3

In [36]: 

2、匿名函数支持 所有的 参数类型

    1)sorted

In [36]: help(sorted)

Help on built-in function sorted in module builtins:

sorted(iterable, /, *, key=None, reverse=False)
    Return a new list containing all items from the iterable in ascending order.
    
    A custom key function can be supplied to customize the sort order, and the
    reverse flag can be set to request the result in descending order.
~
(END)
In [37]: from collections import namedtuple

In [38]: User = namedtuple('u', ['name', 'age'])

In [39]: User
Out[39]: __main__.u

In [40]: users = [User('miracle', 18), User('chenyihan', 17), User('mage', 88)]

In [41]: users
Out[41]: 
[u(name='miracle', age=18),
 u(name='chenyihan', age=17),
 u(name='mage', age=88)]

In [42]: def get_age(user):
    ...:     return user.age
    ...: 

In [43]: users[0].age
Out[43]: 18

In [44]: sorted(users, key=get_age)
Out[44]: 
[u(name='chenyihan', age=17),
 u(name='miracle', age=18),
 u(name='mage', age=88)]

In [45]: get_age(users[2])
Out[45]: 88

In [46]: for user in users:
    ...:     print(get_age(user))
    ...:     
18
17
88

In [47]: lambda x: x.age
Out[47]: <function __main__.<lambda>>

In [48]: sorted(users, key=lambda x: x.age)
Out[48]: 
[u(name='chenyihan', age=17),
 u(name='miracle', age=18),
 u(name='mage', age=88)]

In [49]: 

    2)map

In [49]: help(map)

help on class map in module builtins:

class map(object)
 |  map(func, *iterables) --> map object
 |  
 |  Make an iterator that computes the function using arguments from
 |  each of the iterables.  Stops when the shortest iterable is exhausted.
 |  
 |  Methods defined here:
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __iter__(self, /)
 |      Implement iter(self).
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  __next__(self, /)
 |      Implement next(self).
 |  
 |  __reduce__(...)
 |      Return state information for pickling.
~

(END)
In [50]: map(lambda x: x.age, users)
Out[50]: <map at 0x7fe8d451f668>

In [51]: list(map(lambda x: x.age, users))
Out[51]: [18, 17, 88]

In [52]: list(map(lambda x: x.name, users))
Out[52]: ['miracle', 'chenyihan', 'mage']

In [53]: names = []

In [54]: for user in users:
    ...:     names.append(user.name)
    ...:     

In [55]: map(lambda x: x.name, users)
Out[55]: <map at 0x7fe8d4534e10>

In [56]: 

    3)filter

In [56]: help(filter)

Help on class filter in module builtins:

class filter(object)
 |  filter(function or None, iterable) --> filter object
 |  
 |  Return an iterator yielding those items of iterable for which function(item)
 |  is true. If function is None, return the items that are true.
 |  
 |  Methods defined here:
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __iter__(self, /)
 |      Implement iter(self).
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  __next__(self, /)
 |      Implement next(self).
 |  
 |  __reduce__(...)
 |      Return state information for pickling.
~

(END)
In [57]: list(filter(lambda x: x.age < 30, users))
Out[57]: [u(name='miracle', age=18), u(name='chenyihan', age=17)]

In [58]: 

In [58]: ret = []

In [59]: for user in users:
    ...:     if user.age < 30:
    ...:         ret.append(user)
    ...:         

In [60]: [user for user in users if user.age < 30]
Out[60]: [u(name='miracle', age=18), u(name='chenyihan', age=17)]

In [61]: 

二、生成器

In [4]: def g():
   ...:     for x in range(10):
   ...:         yield x         # 弹出一个值
   ...:         

In [5]: r = g()

In [6]: r
Out[6]: <generator object g at 0x7fd943bd9c50>

In [7]: r.__iter__
Out[7]: <method-wrapper '__iter__' of generator object at 0x7fd943bd9c50>

In [8]: l = range(10)

In [9]: l.__iter__
Out[9]: <method-wrapper '__iter__' of range object at 0x7fd942fa5c00>

In [10]: i = iter(l)

In [11]: i.__next__
Out[11]: <method-wrapper '__next__' of range_iterator object at 0x7fd9439e4f00>

In [12]: next(i)
Out[12]: 0

In [13]: next(l)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-13-cdc8a39da60d> in <module>()
----> 1 next(l)

TypeError: 'range' object is not an iterator

In [14]: next(r)
Out[14]: 0

In [15]: next(r)
Out[15]: 1

In [16]: next(r)
Out[16]: 2

In [17]: next(r)
Out[17]: 3

In [18]: next(r)
Out[18]: 4

In [19]: for x in r:
    ...:     print(x)
    ...:     
5
6
7
8
9

In [20]: next(r)
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-20-8ebe59a56b1d> in <module>()
----> 1 next(r)

StopIteration: 

In [21]: 

In [23]: def gen():
    ...:     print('a')
    ...:     yield 1
    ...:     print('b')
    ...:     yield 2
    ...:     return 3
    ...: 

In [24]: g = gen()

In [25]: g
Out[25]: <generator object gen at 0x7fd943bd9d58>

In [26]: next(g)
a
Out[26]: 1

In [27]: next(g)
b
Out[27]: 2

In [28]: next(g)
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-28-e734f8aca5ac> in <module>()
----> 1 next(g)

StopIteration: 3

In [29]: next(g)
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-29-e734f8aca5ac> in <module>()
----> 1 next(g)

StopIteration: 

In [30]: 


带 yield语句 的函数,称之为 生成器函数, 生成器函数的返回值是 生成器

gen(),           是 生成器函数

g = gen() ,        g 是 生成器

  • 生成器函数 执行的时候,不会执行函数体(这里说的 生成器函数执行, 不是生成器执行的时候)
  • 当next生成器的时候,当前代码会执行到之后的 第一个yield,弹出值,并暂停函数
  • 当再次执行next 生成器的时候,从上次暂停的地方开始往下执行
  • 当没有多余的yield 的时候,会抛出StopIteration 异常, 如果函数有返回值(return),异常的value 就是函数的返回值 
In [31]: next(gen())
a
Out[31]: 1

In [32]: def gen(x):
    ...:     if x == 0:
    ...:         yield x
    ...:         

In [33]: id(gen(0))
Out[33]: 140571121128288

In [34]: def counter():
    ...:     x = 0
    ...:     while True:
    ...:         x += 1
    ...:         yield x
    ...:         

In [35]: def inc(c):
    ...:     return next(c)
    ...: 

In [36]: def _counter():
    ...:     c = 0
    ...:     def inc():
    ...:         nonlocal c
    ...:         c += 1
    ...:         return c
    ...:     return inc
    ...: 

In [37]: c = counter()

In [38]: inc(c)
Out[38]: 1

In [39]: inc(c)
Out[39]: 2

In [40]: inc(c)
Out[40]: 3

In [41]: inc(c)
Out[41]: 4

In [42]: inc(c)
Out[42]: 5

In [43]: inc(c)
Out[43]: 6
...
In [48]: def inc():
    ...:     c = counter()
    ...:     return lambda: next(c)
    ...: 

In [49]: incr = inc()

In [50]: inc()
Out[50]: <function __main__.inc.<locals>.<lambda>>

In [51]: incr()
Out[51]: 1

In [52]: incr()
Out[52]: 2

In [53]: incr()
Out[53]: 3

加上了lambda 之后,inc()变成了 生成器函数了

incr 才是生成器

In [55]: def inc():
    ...:     def counter():
    ...:         x = 0 
    ...:         while True:
    ...:             x += 1
    ...:             yield x
    ...:     c = counter()
    ...:     return lambda: next(c)
    ...:         

In [56]: incr = inc()

In [57]: incr()
Out[57]: 1
...
In [59]: def make_inc():
    ...:     def counter():
    ...:         x = 0
    ...:         while True:
    ...:             x += 1
    ...:             yield x
    ...:     c = counter()
    ...:     return next(c)
    ...:         

In [60]: make_inc()
Out[60]: 1

In [61]: 
  • 用了一个无限大的列表来不断的计数下去
  • 并没有全局变量
  • 对于counter 来说,就是一个闭包
  • c 就是一个counter 的实例
  •  在最后return 的这个匿名函数,每次执行都是引用这个生成器
In [62]: def fib(n):
    ...:     if n == 0:
    ...:         return 1
    ...:     if n == 1:
    ...:         return 1
    ...:     return fib(n-1) + fib(n-2)
    ...: 

In [63]: def _fib():
    ...:     a = 0
    ...:     b = 1
    ...:     while True:
    ...:         a, b = b, a+b
    ...:         yield a
    ...:         

In [64]: f = _fib()

In [65]: for _ in range(1000):
    ...:     next(f)
    ...: print(next(f))
    ...:     
70330367711422815821835254877183549770181269836358732742604905087154537118196933579742249494562611733487750449241765991088186363265450223647106012053374121273867339111198139373125598767690091902245245323403501

In [66]: def fn():
    ...:     while True:
    ...:         pass
    ...:     for i in range(1000000):
    ...:         yield i
    ...:         

In [67]: 

习题:

1. 实现一个扁平化字典

2. base64编码

3. 最长公共子串

转载于:https://my.oschina.net/u/3552459/blog/1563283

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值