11.6.2 关键字变量参数(字典)
关键字变量参数应该为函数定义的最后一个参数,带**。
关键字和非关键字可变长参数都有可能用在同一个函数中,只要关键字字典是最后一个参数并且非关键字元组先于它之前出现。
>>> def newfoo(arg1, arg2, *nkw, **kw):
...print "Firsr arg: ", arg1
...print "Second arg: ", arg2
...print "No keyword args: "
...for arg in nkw:
...print " ", arg
...print "keyword args: "
...for arg_key in kw.keys():
...print " ", kw[arg_key]
...
>>> newfoo(11, 22, 33, '44', '55', a='a', b='b', c=88 )
Firsr arg: 11
Second arg: 22
No keyword args:
33
44
55
keyword args:
a
88
b
>>>
11.6.3 调用带有可变长参数对象函数
>>> newfoo(1, 2, 3, a = 4, *(5, 6, 7), **{'b':8, 'c':9, 'd':10})
Firsr arg: 1
Second arg: 2
No keyword args:
3
5
6
7
keyword args:
4
9
8
10
>>>
注意我们的元组和字典参数仅仅是被调用函数中最终接收的元组和字典的子集。额外的非关键字值‘3’以及‘x’和‘y’关键字对也被包含在最终的参数列表中,而它们不是‘*'和'**'的可变参数中的元素。
11.7 函数式编程
11.7.1 匿名函数与lambda
lambda [arg1 [,arg2 ... argN]] : expression
python允许用lambda关键字创建匿名函数,匿名是因为不需要以标准的方式来声明。
这个表达式的定义体必须和声明放在同一行。
参数是可选的,如果使用参数的话,参数通常也是表达式的一部分。
默认以及可变参数也是允许的。
>>> a = lambda x, y=2: x*y
>>> a(2)
4
>>> a(2, 3)
6
>>> b = lambda *z: z
>>> b(1,2,3)
(1, 2, 3)
>>>
11.7.2 内建函数 apply()、filter()、map()、reduce()
1. apply() 已经淘汰
2. filter()给定一个对象的序列和一个过滤函数,每个序列元素都通过这个过滤器进行筛选,保留函数返回为真的对象。filter函数为已知的序列的每个元素调用给定布尔函数。每个filter返回的非零值元素添加到一个列表中。返回的对象是一个从原始队列中“过滤后”的队列。
>>> from random import randint
>>> def odd(n):
... return n % 2
...
>>> filter(odd, range(10))
[1, 3, 5, 7, 9]
>>>
3. map()
map()将函数调用“映射”到每个序列的元素上,并返回一个含有所有返回值的列表。
可以使用带多个序列的map()
>>> map(lambda x, y: x+y, (1, 2, 3), (4, 5, 6))
[5, 7, 9]
>>>
可以使用map()和一个为None的函数对象来将不相关的序列归并在一起。这种思想在一个新的内建函数zip被加进来之前的python2.0是很普遍的。
>>> map(None, (1, 2, 3), (4, 5, 6))
[(1, 4), (2, 5), (3, 6)]
>>> zip((1, 2, 3), (4, 5, 6))
[(1, 4), (2, 5), (3, 6)]
>>>
4. reduce()
reduce()使用了一个二元函数(一个接收带两个值作为输入,进行了一些计算然后返回一个值作为输出),一个序列,和一个可选的初始化器,卓有成效地将那个列表的内容“减少”为一个单一的值,如同它的名字一样。
reduce()通过取出序列的头两个元素,将他们传入二元函数来获得一个单一的值来实现。然后又用这个值和序列的下一个元素来获得又一个值,然后继续直到整个序列的内容都遍历完毕以及最后的值会被计算出来为止。
如果给定初始化器,那么一开始的迭代会用初始化器和一个序列的元素来进行,接着和正常的一样进行。
>>> print "the total is ", reduce(lambda x, y:x+y, range(1,100), 0)
the total is 4950
>>>