python 一等函数基础

Python 中,函数是一等对象。编程语言理论家把“一等对象定义为满足下述条件的程序实体:

  • 在运行时创建
  • 能赋值给变量或数据结构中的元素
  • 能作为参数传给函数
  • 能作为函数的返回结果

Python 中,整数字符串字典都是一等对象——没什么特别的。人们经常将“把函数视作一等对象”简称为“一等函数”。这样说并不完美,似乎表明这是函数中的特殊群体。在 Python 中,所有函数都是一等对象

1.把函数视作对象

# -*- 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]


2.高阶函数

接受函数为参数,或者把函数作为结果返回的函数是高阶函数。刚才的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']

注意: 列表里的单词没有变,我们只是把反向拼写当作排序条件

在函数式编程范式中,最为人熟知的高阶函数有 mapfilterreduceapplyapply 函数在 Python 2.3 中标记为过时,在 Python 3 中移除了,因为不再需要它了。如果想使用不定量的参数调用函数,可以编写 fn(*args, **keywords),不用再编写 apply(fn, args, kwargs)

3.map、filter和reduce的现代替代品

函数式语言通常会提供 mapfilterreduce 三个高阶函数(有时使用不同的名称)。在Python 3 中,mapfilter 还是内置函数,但是由于引入了列表推导和生成器表达式,它们变得没那么重要了。列表推导或生成器表达式具有 mapfilter 两个函数的功能,而且更易于阅读,如下示例所示。

# -*- 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:

  • allany 也是内置的归约函数。
  • all(iterable) : 如果 iterable 的每个元素都是真值,返回 Trueall([]) 返回 True
  • any(iterable): 只要 iterable 中有元素是真值,就返回 Trueany([]) 返回 False

4.匿名函数

具体见: https://blog.csdn.net/MZP_man/article/details/92385584?spm=1001.2014.3001.5501

你可能感兴趣的:(python)