在 Python
中,函数是一等对象
。编程语言理论家把“一等对象
”定义
为满足下述条件的程序实体:
在 Python
中,整数
、字符串
和字典
都是一等对象
——没什么特别的。人们经常将“把函数视作一等对象
”简称为“一等函数
”。这样说并不完美,似乎表明这是函数中的特殊群体。在 Python
中,所有函数都是一等对象
。
# -*- coding: utf-8 -*-
def factorial(n):
"""returns n!"""
return 1 if n < 2 else n * factorial(n - 1)
if __name__ == '__main__':
print(factorial(3))
# 6
print(factorial.__doc__) # __doc__ 是函数对象众多属性中的一个。
# returns n!
print(type(factorial)) # factorial 是 function 类的实例
#
__doc__
属性用于生成对象的帮助文本,在 Python
交互式控制台中,help
(factorial
) 命令输出的内容。
下面示例展示了函数对象的“一等
”本性。我们可以把 factorial
函数赋值给变量 fact
,然后通过变量名调用。我们还能把它作为参数传给 map
函数。map
函数返回一个可迭代对象
,里面的元素是把第一个参数
(一个函数)应用到第二个参数
(一个可迭代对象,这里是 range(11))中各个元素上得到的结果。
# -*- coding: utf-8 -*-
def factorial(n):
"""returns n!"""
return 1 if n < 2 else n * factorial(n - 1)
if __name__ == '__main__':
fact = factorial
print(fact)
#
print(map(factorial, range(11)))
#
print(list(map(fact, range(11))))
# [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
接受
函数为参数
,或者把函数
作为结果返回
的函数是高阶函数
。刚才的map
函数就是一例,内置函数 sorted
也是:可选的 key
参数用于提供一个函数,它会应用到各个元素上进行排序
,例如,若想根据单词的长度排序,只需把 len
函数传给 key
参数即可。
fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana']
sorted(fruits, key=len)
# ['fig', 'apple', 'cherry', 'banana', 'raspberry', 'strawberry']
任何单参数
函数都能作为 key
参数的值。例如,为了创建押韵词典,可以把各个单词反过来拼写
,然后排序。看下面示例:
def reverse(word):
return word[::-1]
if __name__ == '__main__':
fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana']
print(sorted(fruits, key=reverse))
# ['banana', 'apple', 'fig', 'raspberry', 'strawberry', 'cherry']
注意: 列表里的单词没有变,我们只是把反向拼写
当作排序条件
。
在函数式编程范式中,最为人熟知的高阶函数有 map
、filter
、reduce
和 apply
。apply
函数在 Python 2.3
中标记为过时,在 Python 3
中移除了,因为不再需要它了。如果想使用不定量的参数调用函数,可以编写 fn(*args, **keywords)
,不用再编写 apply(fn, args, kwargs)
。
函数式语言通常会提供 map
、filter
和 reduce
三个高阶函数(有时使用不同的名称)。在Python 3
中,map
和 filter
还是内置函数,但是由于引入了列表推
导和生成器
表达式,它们变得没那么重要了。列表推导或生成器表达式具有 map
和 filter
两个函数的功能,而且更易于阅读,如下示例所示。
# -*- coding: utf-8 -*-
def factorial(n):
"""returns n!"""
return 1 if n < 2 else n * factorial(n - 1)
if __name__ == '__main__':
print(list(map(factorial, range(6))))
# [1, 1, 2, 6, 24, 120]
print([factorial(n) for n in range(6)])
# [1, 1, 2, 6, 24, 120]
print(list(map(factorial, filter(lambda n: n % 2, range(6)))))
# [1, 6, 120]
print([factorial(n) for n in range(6) if n % 2])
# [1, 6, 120]
tips:
all
和 any
也是内置的归约函数。all(iterable)
: 如果 iterable
的每个元素都是真值,返回 True
;all([])
返回 True
。any(iterable)
: 只要 iterable
中有元素是真值,就返回 True
;any([])
返回 False
。具体见: https://blog.csdn.net/MZP_man/article/details/92385584?spm=1001.2014.3001.5501