我们已经准备好了,你呢?

2024我们与您携手共赢,为您的企业形象保驾护航!

说到微积分,经常会和函数式编程纠缠不清。这种设计理念强调抛弃变量和状态,用纯函数的递归系统来构建程序(个人理解)。虽然函数式编程和面向对象编程背道而驰,但并不妨碍借鉴一些有价值的内容。换句话说,不能因为它的存在就认为它是一种函数式编程语言,只是因为它在某些细节上更高效而被引入。比如用来定义匿名函数,和标题提到的apply()等内置函数一起构建一些程序结构。

匿名函数与标准方式声明的函数的区别在于,它不需要def语句,也不需要名字来引用它,直接使用语句就可以获得函数对象,其语法为:

[参数1[,参数2…]]:

参数是可选的,冒号后面跟着一个表达式,函数返回这个表达式的值,在def语句中,相当于:

def func([arg1[,arg2…]]):

可以看到函数没有中间状态,不适合构建过于复杂的函数,因为它们的函数体只有一个表达式。因此,它们大多用于构建临时的、简单的、不可重用的小函数。虽然原则上你可以给函数起一个别名,如下所示,以供后续引用。但如果你打算重用这个函数,为什么不使用 def 语句定义一个标准函数,它具有更多的功能并且更易于维护。

>>> foo = lambda a,b: a+b
>>> foo(1,2)
3

(), 地图(), ():

apply()函数放在最后,因为涉及变长参数,并且和其他三个函数功能不一样,而()、map()、()三个内置函数的功能同属一类,都是对可迭代对象进行处理并返回结果。

( or None, ) --> 该函数正如其名称一样,使用可迭代对象中的每个元素作为参数调用布尔函数,返回迭代器中所有返回 True 的元素。如果为 None,则返回值为 True 的元素。示例:

>>> a = filter(lambda x:x>2,[1,2,3,4])
>>> type(a)

>>> for i in a:print(i)
3
4
>>>

在之前的版本中,() 函数返回的是一个列表,但后来改为返回一个迭代器,所以上面的例子使用 for 语句来显示结果。关于返回迭代器还有一点需要注意,就是上面例子中的 a 中的元素并不是在赋值时一次生成的,所以如果使用的元素调用会产生异常,那么这个异常其实是在 for 循环中抛出的。可以看出,在这种“过滤元素”的应用环境中,我们需要的函数形式很简单,只有一个表达式,所以使用 是一个不错的选择。(其实下面两个函数也是一样)

map(func, *) --> map 将函数 func 应用于 的每个元素,并以迭代器的形式返回结果。请注意,您可以在此处提供多个参数。如果这样做,当您调用 func 时,它将依次从每个元素中取出一个元素,直到用尽最短的元素。因此 func 的参数数量应等于 的数量。

>>> a = map(lambda x,y:x+y,[1,2,3],[3,2,1])
>>> type(a)

>>> for i in a:print(i)
4
4
4

(, [, ]) –> value 函数是:接受两个参数,第一个是,第二个是 的第一个元素。如果没有提供,则取前两个元素。然后将本次调用的返回值作为第一个参数传递,第二个参数是 的下一个元素。如此循环下去,返回最终的值。因为 () 函数不再是 中的内置函数,需要 from 才能使用它,所以这里就不举例了。

其实不仅如此,在当前版本中这三个函数已经没什么用了。()和map()都可以用列表推导式(生成器表达式)来代替,而且显然列表推导式更加高级和好用。所以一般来说,知道这几个函数是干什么用的就够了,基本没必要真正去用。不过下面这个用来代替map()的列表推导式例子,好像只适用于单容器的情况,对于多容器的情况,想不出上面map()的例子该怎么写……

>>> [x for x in [1,2,3,4] if x>2]# filter
[3, 4]
>>> [x+1 for x in [1,2,3]]# map
[2, 3, 4]

Apply() 比 () 更糟糕,在 中已经不存在了。这是因为它从 1.6 版本开始就不再使用了。我们在这里仍然提到它只是为了介绍下一个主题:可变长度参数。事实上,在 1.6 之前,函数不支持可变长度参数,apply() 就是为此而生的。它可以使用可变长度参数来调用函数。

可变长度参数:

可变长度参数意味着:调用函数时不知道要传入多少个参数,可能没有,也可能有 100 多个。比如计算电子账单总额时,谁知道会有多少项呢?虽然像这样的问题,还有很多其他方法可以将金额加在一起,但使用单个函数来实现它总是能收获额外的好处。而且,虽然可变长度参数的功能也可以用元组来实现,但下面介绍的方法可以做得更好。定义函数时可以使用的参数的完整形式如下:

定义函数(,,*,**):

这四种参数形式都是独立可选的,前两种就不展示了,后面带*和**的是变长参数,位置上带*的必须放在不带*的后面,否则会报错,比如模块里有一个add()函数:

add(a, b)——与 a + b 相同。

此函数仅接受两个参数。如果我们使用可变长度参数,我们可以让它接受无限数量的参数并返回它们的总和:

>>> def add(*args):
	result = 0
	for num in args:
		result += num
	return result
>>> add(1,2,3,4)
10
>>> add(*(1,2,3,4))
10
>>> add(1,2,*(3,4))
10

从上面的例子就可以看出*的作用了,只要参数中有*args,那么函数就会自动接受所有非关键字参数,并且把接收到的参数全部放入一个元组中。

但是这个函数和 add() 相比有一个缺点,add() 不仅可以加数字,还可以连接字符串,而我们定义的这个只能处理数字。所以接下来我们要把位置参数 () 和变长非关键字参数 (*) 结合起来使用,这也是一个能体现它们之间联系的例子:

>>> def add(first,*args):
	result = first
	checked = type(first)
	for item in [x for x in args if type(x)==checked]:
		result += item
	return result
>>> add(1,2,3,4)
10
>>> add('1','2','3','4')
'1234'
>>> add(1,2,'3','4')
3
>>> add(*(1,2,3,4))
10

这里我们从 *args 中分离出了一个非关键字参数,并将其命名为 first。只有与 first 类型相同的参数才会被加在一起。你可以看到 *args 自动将第一个参数让给 first,而只包含其余的参数。无论你单独传入第一个参数,还是使用 *() 一次性传入所有参数,函数都会以相同的方式处理它们。

突然想起上面的例子,int 和 float 参数还是不能相加的。所以我们可以把判断改成:if type(x) in (int,float) 像这样。

关键字参数的表现与非关键字参数相同,这里就不再赘述了。

二维码
扫一扫在手机端查看

本文链接:https://by928.com/4670.html     转载请注明出处和本文链接!请遵守 《网站协议》
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求,请立即点击咨询我们或拨打咨询热线: 13761152229,我们会详细为你一一解答你心中的疑难。

项目经理在线

我们已经准备好了,你呢?

2020我们与您携手共赢,为您的企业形象保驾护航!

在线客服
联系方式

热线电话

13761152229

上班时间

周一到周五

公司电话

二维码
微信
线