lambda表达式可以让你写出优美,简洁的代码."黑客与画家"列举的事例足以证明函数式编程的强大之处,也更加证明了人月就是一个神话.

1,lambda 格式

lambda 关键字后面跟一个或多个参数,紧跟一个冒号,最后面是一个表达式,例如: 

lambda x,y,z : x+y+z

lambda是一个表达式而不是一个语句,它能够出现在不允许def出现的地方。作为表达式(简单函数),lambda返回一个值。

lambda和def最大的区别是:lambda用来编写简单的函数,而def用来处理更强大的任务。

示例:

  1. f = lambda x,y,z : x+y+z  
  2. print f(1,2,3)  
  3.   
  4. g = lambda x,y=2,z=3 : x+y+z  
  5. print g(1,z=4,y=5)  
  6. print g(10)  

输出结果为:

  1. 6  
  2. 10  
  3. 15

 

2,lambda跳转

lambda表达式常用来编写跳转表(jump table),就是行为的列表或字典

示例:

  1. L = [(lambda x: x**2),  
  2.      (lambda x: x**3),  
  3.      (lambda x: x**4)
  4.     ]  
  5. print L[0](2),L[1](2),L[2](2)  
  6.   
  7. D = {'f1' : (lambda2+3),  
  8.      'f2' : (lambda2*3),  
  9.      'f3' : (lambda2**3)
  10.      }  
  11. print D['f1'](),D['f2'](),D['f3']() 

输出结果为:

  1. 4 8 16  
  2. 5 6 8  

注意: L[0](2),L[1](2),L[2](2) 第一个方括号参数,选择数组下标;第二个小括号参数,传入表达式参数

 

3,lambda嵌套

示例:

>>> def add(x):
...     return lambda y:x+y
... 
>>> lmd = add(2)
>>> lmd(20)
22
>>> 
>>> lmd = lambda x: lambda y : x+y
>>> a = lmd(3)
>>> a(10)
13
>>> 
>>> (lmd(3))(10)
13

说明:

1) def add(x) 定义了一个函数,返回一个lambda表达式,

2) lmd = add(2) 通过def函数返回并转化为表达式 lmd = lambda y:2+y

3) lmd(20) 实际是传参执行lambda表示式,y = 20, 输入 2+20 = 22

4) lmd = lambda x: lambda y : x+y 为嵌套lambda表达式

5) a = lmd(3) 实际是传参执行第一层lambda表达式为 a = lambda y : 3+y

6) a(10) 实际是传参执行第二层lambda表达式 y = 10, 输入 3+10 = 13

7) (lmd(3))(10) 是5和6的合集,且 (lmd(3)) 必须加上括号表示一个整体,形如 (lambda y : 3+y)(10)

lambda表达式可以嵌套使用,但是从可读性的角度来说,应尽量避免使用嵌套的lambda表达式。

 

4,lambda/map

map函数可以在序列中映射函数进行操作

示例:

  1. def inc(x):  
  2.     return x+10  
  3.       
  4. L = [1,2,3,4]  
  5. print map(inc,L)  
  6. print map((lambda x: x+10),L)  

输出结果为:

  1. [11121314]  
  2. [11121314]  

说明: lambda表达式在某些场合,可以替代简单def函数实现的功能

 

5,lambda/list

list列表解析可以实现map函数同样的功能,而且往往比map要快。

示例:

  1. print [x**2 for x in range(10)]  
  2. print map((lambda x: x**2), range(10))  

输出结果为:

  1. [0149162536496481]  
  2. [0149162536496481]  

 

6,列表解析比map更强大

示例:

  1. print [x+y for x in range(5if x%2 == 0 for y in range(10if y%2 ==1]  

输出结果为:

  1. [135793579115791113]  

说明: 

上面list列表实际是一个二层循环的结构体

1) 第二层循环 for y in range(10) if y%2 ==1 输出结果为 [1, 3, 5, 7, 9]

2) 第一层循环 for x in range(5) if x%2 == 0  输出结果为 [0, 2, 4]

3) 两层循环相加计算得 [1, 3, 5, 7, 9, 3, 5, 7, 9, 11, 5, 7, 9, 11, 13]

 

7,生成器函数就像一般的函数,但它们被用作实现迭代协议,因此生成器函数只能在迭代语境中出现

示例:

  1. def gen(N):  
  2.     for i in range(N):  
  3.         yield i**2    
  4. for i in gen(5):  
  5.     print i,  

输出结果为:

  1. 0 1 4 9 16  

说明: yield协程使用迭代器实现,类似于 for y in (x**2 for x in range(5)):  print y 小括号实现,而不同于 [x**2 for x in xrange(5)] 的中括号实现,需要注意区分

 

8,所有的迭代内容(包括for循环、map调用、list列表解析等等)将会自动调用iter函数,来看看是不是支持了迭代协议。

 

9,生成器表达式就像列表解析一样,但它们是扩在圆括号()中而不是方括号[]中。例如:

  1. for num in (x**2 for x in range(5)):  
  2.     print num,  

输出结果为:

  1. 0 1 4 9 16  

 

10,列表解析比for循环具有更好的性能

尽管如此,在编写Python代码时,性能不应该是最优先考虑的,可读性同样是重要的。

 

11,没有return语句时,函数将返回None对象

 

12,函数设计的概念:

  • 耦合性:只有在真正必要的情况下才使用全局变量
  • 耦合性:不要改变可变类型的参数,除非调用者希望这样做
  • 耦合性:避免直接改变另一个文件模块中的变量
  • 聚合性:每一个函数都应有一个单一的、统一的目标

 

13,最后给个默认参数和可变参数的例子:

  1. def saver(x=[]):  
  2.     x.append(1)  
  3.     print x  
  4.       
  5. saver([2])  
  6. saver()  
  7. saver()  
  8. saver()  

输出结果为:

  1. [21]  
  2. [1]  
  3. [11]  
  4. [111]  

 

 

参考推荐

Python中的dict, list, tuple, set 实例

Python学习入门(11)——排序

Python学习入门(2)——数组