【函数】03、匿名函数及生成器函数

简介:

一、匿名函数

1、定义

语法格式:

   lambda args:expression

      args:以逗号分隔的参数列表

      expression:用到args中各参数的表达式

      lambda定义的代码必须是合法的表达式不能出现多条件语句(可使用if的三元表达式)和非表达式,如for和while等

  lambda的首要用途是指定短小的回调函数

  lambda将返回一个函数而不是将函数赋值给某变量名


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
In [77]: lambda x: x+1
Out[77]: < function  __main__.<lambda>>
 
In [78]: f = lambda x: x+1
 
In [79]:  type (f)
Out[79]:  function
 
In [80]: f(1)
Out[80]: 2
 
In [81]: f(2)
Out[81]: 3
 
 
# 也可以直接使用小括号也调用匿名函数
 
In [88]: lambda x: x+1
Out[88]: < function  __main__.<lambda>>
 
In [89]: (lambda x: x+1)               
Out[89]: < function  __main__.<lambda>>
 
In [90]: (lambda x: x+1)(3)    # 第一个小括号用来改变优先级,第二个表示调用函数
Out[90]: 4


总结:

   匿名函数使用lambda定义, lambda是一个表达式而非语句

  匿名函数(lambda表达式)只能写在一行上,所有也有人叫它单行函数

   lamdba是一个单个表达式,而不是一个代码块

   参数列表不需要使用小括号

   冒号不是用来开启新的语句块,而是分隔参数列表和表达式

   没有return语句,最后一个表达式的值即为返回值

   def语句创建的函数将赋值给某变量名,而lambda表达式直接返回函数

   lambda也支持使用默认参数,关键字参数,可变参数,参数解构   

1
2
3
4
5
6
7
8
9
10
11
In [130]: (lambda : 0)()
Out[130]: 0
 
In [131]: (lambda x: 0)(1)
Out[131]: 0
 
In [132]: (lambda x, y: x+y)(3, 5)
Out[132]: 8
 
In [133]: (lambda *args, **kwargs: print(args, kwargs)) (*range(3), **{str(x):x  for  in  range(3)})
(0, 1, 2) { '0' : 0,  '1' : 1,  '2' : 2}



匿名函数常用于高阶函数中参数传递参数(当此函数参数非常短小时)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
In [136]: 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 [146]: lst = [1, 3, 5, 7, 2, 4, 6, 8]
In [146]: lst = [1, 3, 5, 7, 2, 4, 6, 8]
 
In [147]: sorted(lst)
Out[147]: [1, 2, 3, 4, 5, 6, 7, 8]
 
In [148]: sorted(lst, reverse=True)
Out[148]: [8, 7, 6, 5, 4, 3, 2, 1]
 
 
In [149]: lst == [1, 3, 5,  "x" "xxj" "j" , 2]
Out[149]: False
 
In [150]: lst = [1, 3, 5,  "x" "xxj" "j" , 2]
 
In [151]: sorted(lst)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-151-904d7ad462e2>  in  <module>()
----> 1 sorted(lst)
 
TypeError:  '<'  not supported between instances of  'str'  and  'int'
 
In [152]: lst. sort ()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-152-e0fe8579802d>  in  <module>()
----> 1 lst. sort ()
 
TypeError:  '<'  not supported between instances of  'str'  and  'int'


二、生成器

1、生成器函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
In [161]: def g():
      ...:      for  in  range(10):
      ...:         yield x          # 表示弹出一个值
      ...:         
 
In [162]: r =g
 
In [163]:  type (r)
Out[163]:  function
 
In [164]: r = g()    # 此时函数已经执行完成了,函数讲道理已经被销毁了;但事实上没有被销毁
这是生成器函数和普通函数的区别
 
In [165]:  type (r)
Out[165]: generator
 
In [166]: r
Out[166]: <generator object g at 0x7f7c20cdc938>
 
 
In [161]: def g():
      ...:      for  in  range(10):
      ...:         yield x
      ...:         
      
In [169]: next(r)
Out[169]: 0
 
In [170]: next(r)
Out[170]: 1
 
In [171]: next(r)
Out[171]: 2
 
In [172]: next(r)
Out[172]: 3


生成器函数的工作过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
In [174]: def gen():
      ...:     print( 'a' )
      ...:     yield 1
      ...:     print( 'b' )
      ...:     yield 2
      ...:     print( 'c' )
      ...:      return  3
      ...:     
 
In [175]: g = gen()
 
In [176]: g
Out[176]: <generator object gen at 0x7f7c20cdc620>
 
In [177]: next(g)
a
Out[177]: 1
 
In [178]: next(g)
b
Out[178]: 2
 
In [185]: def gen():
      ...:     print( 'a' )
      ...:     yield 1
      ...:     print( 'b' )
      ...:     yield 2
      ...:     print( 'c' )
      ...:      return  3
      ...:     
 
In [186]: g = gen()    # 执行生成器函数的时候,函数体并没有被执行
   
In [187]: g
Out[187]: <generator object gen at 0x7f7c2025f938>
 
In [188]: next(g)     # 第一个next时,执行到第一个yield,停止执行
a
Out[188]: 1
 
In [189]: next(g)     # 第2个next时,从第1个yield之后开始执行到第2个yield,停止执行
b
Out[189]: 2
 
In [190]: next(g)     # 第3次next时,从第2个yield之后开始执行,当没有更多yield时,抛出
StopIteration,异常的值是函数的返回值
 
c
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-190-5f315c5de15b>  in  <module>()
----> 1 next(g)
 
StopIteration: 3
 
In [197]: next(g)
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-197-5f315c5de15b>  in  <module>()
----> 1 next(g)
 
StopIteration: 
 
 
 
In [193]: def gen():
      ...:     print( 'a' )
      ...:     yield 1
      ...:     print( 'b' )
      ...:     yield 2
      ...:     print( 'c' )
      ...:     
 
In [194]: g = gen()
 
In [195]: next(g)
a
Out[195]: 1
 
In [196]: next(g)
b
Out[196]: 2
 
In [197]: next(g)
c
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-197-5f315c5de15b>  in  <module>()
----> 1 next(g)
 
StopIteration:        # 生成器函数没有返回值时,StopIteration也没有值


总结:

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

  生成器是特殊的迭代器

  生成器函数执行的时候,不会执行函数体

  当next生成器的时候,当前代码执行到第一个yield,会弹出值,并暂停函数

  当再次next生成器时,从上次暂停处开始往下执行到下一个yield

  当没有多余的yield的时候,会抛出StopIteration异常,异常的Value是函数的返回值

  

  生成器是惰性求值的


可用于作计数器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
In [7]: def counter():
    ...:     x = 0
    ...:      while  True:
    ...:         x += 1
    ...:         yield x
    ...:         
 
In [8]: def inc():
    ...:     c = counter()
    ...:      return  lambda: next(c)
    ...: 
 
In [9]: g = inc()
 
In [10]: g()
Out[10]: 1
 
In [11]: g()
Out[11]: 2
 
In [12]: g()
Out[12]: 3


节省内存:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
In [14]: def bib():
     ...:     a = 0
     ...:     b = 1
     ...:      while  True:
     ...:         a, b = b, a+b
     ...:         yield a
     ...:         
 
In [15]: g = bib()
 
In [16]: g
Out[16]: <generator object bib at 0x7fb26f6bf990>
 
In [17]: next(g)
Out[17]: 1
 
In [18]: next(g)
Out[18]: 1
 
In [19]: next(g)
Out[19]: 2
 
In [20]: next(g)
Out[20]: 3
 
In [21]: next(g)
Out[21]: 5


协程 -- 生成器的高级用法

  协程运行在一个线程内,在用户态调度;也被称为轻量线程

调度就是由调度器来决定哪段代码占用CPU时间

由系统内核调度的是内核态调度

用户自己写代码实现调度器来调度是用户态调度

非抢占式调度

















本文转自xiexiaojun51CTO博客,原文链接:http://blog.51cto.com/xiexiaojun/1937280 ,如需转载请自行联系原作者

相关文章
|
1月前
|
存储 编译器 C++
|
7天前
|
存储
07-python函数的进阶-函数的多返回值/函数的多种传参方式/匿名函数/lambda函数
07-python函数的进阶-函数的多返回值/函数的多种传参方式/匿名函数/lambda函数
|
8月前
|
C语言
C语言知识点之 函数2
C语言知识点之 函数2
31 0
|
6月前
|
程序员
函数
一、函数 函数是一段封装了特定功能的可重复使用的代码块。它接受输入参数,执行特定的操作,并返回一个结果。函数可以在程序中被多次调用,避免了重复编写相同的代码,提高了代码的复用性和可维护性。 函数通常具有以下几个特点: 1. 输入参数:函数可以接受零个或多个输入参数,用于传递数据给函数。输入参数可以是任意类型的数据,如整数、浮点数、字符串、数组等。函数可以使用输入参数来执行特定的操作。 2. 函数体:函数体是函数的核心部分,包含了函数要执行的操作。函数体是由一系列的语句组成的代码块,可以包含各种控制语句、变量声明、表达式等。函数体定义了函数的具体功能。 3. 返回值:函数可以返回一个结果给调用者
33 0
|
8月前
|
算法 程序员 信息无障碍
从零带你认识函数(二)
从零带你认识函数
61 1
|
9月前
|
编译器
函函函函函函函函函函函数——two
函函函函函函函函函函函数——two
69 0
函函函函函函函函函函函数——two
|
12月前
|
自然语言处理 C++
C/C++ 中的 atol()、atoll() 和 atof() 函数
1.atol(): 此函数将作为参数传递给函数调用的 C 类型字符串转换为长整数。它解析 C 字符串 str 并将其内容解释为整数,该整数作为 long int 类型的值返回。该函数会丢弃字符串开头的空白字符,直到找到非空白字符。如果 C 字符串 str 中的非空白字符序列不是有效的整数,或者如果因为 str 为空或仅包含空白字符而不存在这样的序列,则不执行任何转换并返回零。
144 0
|
编译器
【C++Primer】第6章:函数
【C++Primer】第6章:函数
【C++Primer】第6章:函数