博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
匿名函数_ 生成器
阅读量:6257 次
发布时间:2019-06-22

本文共 10084 字,大约阅读时间需要 33 分钟。

hot3.png

一、匿名函数

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

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

In [1]: lambda x: x + 1      # lambda 后面有一个参数x, 然后定义一个函数体, 冒号不换行 Out[1]: 
>In [2]: def fn(x): ...: return x + 1 ...: In [3]: (lambda x: x + 1)(3) # lambda x: x + 1 定义函数Out[3]: 4In [4]: fn(3)Out[4]: 4In [5]:

匿名函数的几个特点:

  • 用lambda 关键字来定义
  • 参数列表 不需要用 圆括号括起来
  • 冒号 不是用来开启新的语句
  • 最后一个表达式 没有return语句,最后一个表达式的值 就是我们的返回值
In [5]: f = fn(3)In [6]: fOut[6]: 4In [7]: def counter():   ...:     c = 0   ...:     def inc():   ...:         nonlocal c   ...:         c += 1   ...:         return c   ...:     return inc   ...: In [8]: f = counter()In [9]: fOut[9]: 
.inc>In [10]: f()Out[10]: 1In [11]: counter()()Out[11]: 1In [12]: f = lambda x: x + 1In [13]: fOut[13]:
>In [14]: f(3)Out[14]: 4In [15]: f = fnIn [16]: f(3)Out[16]: 4
f = lambda x: if x < 0 : # 匿名函数只能写在一行里,因为只能写在一行里,所以 python中的匿名函数又称为 单行函数    0    else:        xFile "
", 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]: 8In [19]: (lambda x,y: x + y)(3, 5)  # 多个 参数Out[19]: 8In [20]: def fn(x, y=3):            # 默认 参数     ...:     return x + y    ...: In [21]: fn(3)Out[21]: 6In [22]: (lambda x,y=3: x + y)(3)    # 默认 参数Out[22]: 6In [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]: TrueIn [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 参数3In [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 namedtupleIn [38]: User = namedtuple('u', ['name', 'age'])In [39]: UserOut[39]: __main__.uIn [40]: users = [User('miracle', 18), User('chenyihan', 17), User('mage', 88)]In [41]: usersOut[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].ageOut[43]: 18In [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]: 88In [46]: for user in users:    ...:     print(get_age(user))    ...:     181788In [47]: lambda x: x.ageOut[47]: 
>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]: 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]: 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]: rOut[6]: 
In [7]: r.__iter__Out[7]:
In [8]: l = range(10)In [9]: l.__iter__Out[9]:
In [10]: i = iter(l)In [11]: i.__next__Out[11]:
In [12]: next(i)Out[12]: 0In [13]: next(l)---------------------------------------------------------------------------TypeError Traceback (most recent call last)
in
()----> 1 next(l)TypeError: 'range' object is not an iteratorIn [14]: next(r)Out[14]: 0In [15]: next(r)Out[15]: 1In [16]: next(r)Out[16]: 2In [17]: next(r)Out[17]: 3In [18]: next(r)Out[18]: 4In [19]: for x in r: ...: print(x) ...: 56789In [20]: next(r)---------------------------------------------------------------------------StopIteration Traceback (most recent call last)
in
()----> 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]: gOut[25]: 
In [26]: next(g)aOut[26]: 1In [27]: next(g)bOut[27]: 2In [28]: next(g)---------------------------------------------------------------------------StopIteration Traceback (most recent call last)
in
()----> 1 next(g)StopIteration: 3In [29]: next(g)---------------------------------------------------------------------------StopIteration Traceback (most recent call last)
in
()----> 1 next(g)StopIteration: In [30]:

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

gen(),           是 生成器函数

g = gen() ,        g 是 生成器

  • 生成器函数 执行的时候,不会执行函数体(这里说的 生成器函数执行, 不是生成器执行的时候)
  • 当next生成器的时候,当前代码会执行到之后的 第一个yield,弹出值,并暂停函数
  • 当再次执行next 生成器的时候,从上次暂停的地方开始往下执行
  • 当没有多余的yield 的时候,会抛出StopIteration 异常, 如果函数有返回值(return),异常的value 就是函数的返回值 
In [31]: next(gen())aOut[31]: 1In [32]: def gen(x):    ...:     if x == 0:    ...:         yield x    ...:         In [33]: id(gen(0))Out[33]: 140571121128288In [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]: 1In [39]: inc(c)Out[39]: 2In [40]: inc(c)Out[40]: 3In [41]: inc(c)Out[41]: 4In [42]: inc(c)Out[42]: 5In [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]: 
.
>In [51]: incr()Out[51]: 1In [52]: incr()Out[52]: 2In [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]: 1In [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))    ...:     70330367711422815821835254877183549770181269836358732742604905087154537118196933579742249494562611733487750449241765991088186363265450223647106012053374121273867339111198139373125598767690091902245245323403501In [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

你可能感兴趣的文章
代理模式
查看>>
OPC DA 到 OPC UA
查看>>
CLR读书笔记--第一章 CLR的执行模型
查看>>
逆向分析(工具介绍)
查看>>
如何优雅地使用Markdown (Sublime 3 + MarkdownEditing+OmniMarkupPreviewer)
查看>>
【Kernel学习】基础篇——01一些标准宏定义和文件include关系
查看>>
hdu1503
查看>>
ES6模块的import和export用法
查看>>
easyui datagrid 搜索功能
查看>>
利用协程爬网页,自动切换io 精典案例:
查看>>
Ubuntu Server14.04 32位安装odoo8.0简单方法
查看>>
go练习3 --map的操作
查看>>
js 获取两个日期相差的天数--自定义方法
查看>>
C++中map的用法
查看>>
QTP录制后弹出框一个或多个ActiveX控件无法显示的解决方法
查看>>
js大文件分割上传
查看>>
Codeforces 614E - Necklace
查看>>
MongoDB非正常关闭后修复记录
查看>>
webstom 快捷键
查看>>
【转载】企业服务总线Enterprise service bus介绍
查看>>