1.关于Python的可变参数
首先我们先来定义两个函数build1()
与build2()
.然后分别调用这两个函数。
def build1(agr):
for x in agr:
print x*x
结果:
>>> build1([1,2,3])
1
4
9
>>>
image.png
def build2(*agr):
for x in agr:
print x*x
结果:
>>> build2([1,2,3])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in build2
TypeError: can't multiply sequence by non-int of type 'list'
为什么当传入一个list
会报错尼?首先我们要明白可变参数的定义。参考廖雪峰的python教程。
可变参数
在Python函数中,还可以定义可变参数。顾名思义,可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。要定义出这个函数,我们必须确定输入的参数。由于参数个数不确定,我们首先想到可以把a,b,c……作为一个list或tuple传进来。
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
在函数内部,参数numbers接收到的是一个tuple.所以当像前边提到过的build2([1,2,3])
例子,函数内部接受到的参数应该是([1,2,3],)
。
所以会有TypeError: can't multiply sequence by non-int of type 'list'
错误。
>>> def f(*agr):
... print agr
...
>>> f([1,2,3])
([1, 2, 3],)
>>>
要想使build2()
函数能够实现接收一个list
并打印出每个元素的平方。可以采用下面的方法:
>>> def build3(*agr):
... for i in agr:
... for x in i:
... print x*x
...
...
>>> build3([1,2,3])
1
4
9
又或者使用下面的方法:
>>> k = [1,2,3]
>>> build2(*k)
1
4
9
>>>
2.Python的匿名函数
>>> def build(agr):
... (lambda x: x*x) for x in agr
File "<stdin>", line 2
(lambda x: x*x) for x in agr
^
SyntaxError: invalid syntax
匿名函数的定义为lambda parameter_list: expression
上面的错误例子将列表推导式的定义混淆了。
>>> def build(agr):
... [(lambda x:x*x) for x in agr]
...
>>> build([1,2,3])
>>>
上面的例子的返回值为None
函数体内部可以用return
随时返回函数结果;
函数执行完毕也没有return
语句时,自动return None
。
所以要加入return
>>> def build(agr):
... return [(lambda x:x*x) for x in agr]
...
>>> build([1,2,3])
[<function <lambda> at 0xb6ed94c4>, <function <lambda> at 0xb6ed948c>, <function <lambda> at 0xb6ed9534>]
当就算就算加入了return
语句,函数还是没有返回预想中的值。返回的是匿名函数的内存地址。原因是匿名函数没有调用。
于是继续将函数改为如下:
>>> def build(agr):
... for x in agr:
... k = lambda m: m*m
... return [k(x)]
...
>>> build([1,2,3])
[1]
结果就打印了一个元素,跟我们设想的[1,4,9]
不同。原因是
函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回.
函数不会因为循环而不断执行return
最后,将函数改为如下:
>>> def build(agr):
... fs = []
... for x in agr:
... k = lambda m: m*m
... fs.append(k(x))
... return fs
...
>>> build([1,2,3])
[1, 4, 9]
终于得到了我们想要的结果了。函数的内部定义了匿名函数,而后又在里面调用了匿名函数。
如果让build()
返回函数并调用,又可以将函数改为如何:
>>> def build(agr):
... fs = []
... for x in agr:
... k = lambda m: m*m
... fs.append(k)
... return fs
...
>>> build([1,2,3])
[<function <lambda> at 0xb6f27294>, <function <lambda> at 0xb6f272cc>, <function <lambda> at 0xb6f2725c>]
>>> build([1,2,3])[1](10)
100
>>>
上面的函数调用build([1,2,3])
会返回一个包含有三个匿名函数的list
.要调用他们,就必选那一个函数并存入参数。所以才会有build([1,2,3])[1](10)
.
为了进一步理解使用可变参数,并使用匿名函数,可以修改代码如下:
>>> def build(*agr):
... fs=[]
... for i in agr:
... for x in i:
... k = lambda m: m*m
... fs.append(k(x))
... return fs
...
>>> build([1,2,3])
[1, 4, 9]
>>>
def build(*agr):
fs=[]
for i in agr:
for x in i:
k = lambda m: m*m
print k(x)
匿名函数lambda
有很多限制,为了加深对python的理解,所以才在上面的例子里面一直使用lambda
.
网友评论