• 一等函数


    在python中,支持面向对象,也支持面向过程编程。字典,整数等这些都是对象,那么函数呢?答案:函数也是对象,在python中,一切都是对象。

    一、函数也是对象

    实例

    def funca():  # 创建一个函数
        """返回ok"""
        return 'ok'
    
    print(funca.__doc__) 
    print(funca)
    print(funca()) 
    type(funca) 
    

    输出

    返回ok  #  __doc__ 是函数对象众多属性中的一个
    <function funca at 0x00000257BDAC2598>  # 函数对象在内存中的地址
    ok  # 函数的返回值
    function  # funca 是 function 类的实例
    

    为了更进一步说明函数式对象,可以把函数赋值给其他变量,或者把函数对象作为参数传递给其他函数。

    >>> fact = factorial
    >>> fact
    <function factorial at 0x...>
    >>> fact(5)
    120
    >>> map(factorial, range(11))
    <map object at 0x...>
    >>> list(map(fact, range(11)))
    [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
    

    二、高阶函数

    什么是高阶函数:接受函数为参数,或者把函数作为结果返回的函数是高阶函数
    常见高阶函数

    - map
    - filter
    - reduce
    - apply
    - sorted
    

    1、 sorted

    内置函数 sorted :可选的 key 参数用于提供一个函数,它会应用到各个元素上进行排序

    实例一、

    根据单词长度给一个列表排序,据单词的长度排序,只需把 len 函数传给 key 参数

    >>> fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana']
    >>> sorted(fruits, key=len)
    ['fig', 'apple', 'cherry', 'banana', 'raspberry', 'strawberry']
    >>
    

    实例二、

    根据反向拼写给一个单词列表排序,下面例子中列表里的单词没有变,我们只是把反向拼写当作排序条件

    >>> def reverse(word):
    ... return word[::-1]
    >>> reverse('testing')
    'gnitset'
    >>> sorted(fruits, key=reverse)
    ['banana', 'apple', 'fig', 'raspberry', 'strawberry', 'cherry']
    >>>
    

    2、map

    map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。

    实例一、

    有一个函数f(x)=x2,要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()实现如下

    >>> def f(x):
    ...     return x * x
    ...
    >>> map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])  # map()传入的第一个参数是f,即函数对象本身。
    [1, 4, 9, 16, 25, 36, 49, 64, 81]
    

    实例二、

    把这个list所有数字转为字符串

    >>> map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])
    ['1', '2', '3', '4', '5', '6', '7', '8', '9']
    

    3、 reduce

    reduce() 函数会对参数序列中元素进行累积。
    函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。

    实例一、

    >>> from functools import reduce  # 在python3,reduce不在作为内置函数出现
    >>> from operator import add 
    >>> reduce(add, range(100)) 
    4950
    >>> sum(range(100)) 
    4950
    >>>
    
    >>> def fn(x, y):
    ...     return x * 10 + y
    ...
    >>> reduce(fn, [1, 3, 5, 7, 9])  # 将序列直接转化成整数
    13579
    

    实例二、

    将一个str对象转化内int对象

    >>> def fn(x, y):
    ...     return x * 10 + y
    ...
    >>> def char2num(s):
    ...     return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
    ...
    >>> reduce(fn, map(char2num, '13579'))
    13579
    

    参考自廖雪峰教程

    4、filter

    filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。
    该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。

    实例

    在一个list中,删掉偶数,只保留奇数,可以这么写:

    def is_odd(n):
        return n % 2 == 1
    
    filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])
    # 结果: [1, 5, 9, 15]
    

    5、map和filter的替代品

    在 Python 3 中,map 和 filter 还是内置函数,但是由于引入了列表推导和生成器表达式,它们变得没那么重要了。列表推导或生成器表达式具有 map 和 filter 两个函数的功能,而且更易于阅读,
    计算阶乘列表:map 和 filter 与列表推导比较

    >>> list(map(fact, range(6))) 
    [1, 1, 2, 6, 24, 120]
    >>> [fact(n) for n in range(6)] 
    [1, 1, 2, 6, 24, 120]
    >>> list(map(factorial, filter(lambda n: n % 2, range(6)))) 
    [1, 6, 120]
    >>> [factorial(n) for n in range(6) if n % 2] 
    [1, 6, 120]
    >>>
    

    6、 any和all

    • all(iterable):如果 iterable 的每个元素都是真值,返回 True;all([]) 返回True。
    • any(iterable):只要 iterable 中有元素是真值,就返回 True;any([]) 返回False。

    三、匿名函数

    lambda 关键字在 Python 表达式内创建匿名函数。匿名函数是为了解决函数对象的命名繁琐而存在的,但是使用匿名函数又大大降低了代码的可阅读性,所以除了在高阶函数将匿名函数作为参数以外,很少使用匿名函数。
    在参数列表中最适合使用匿名函数。
    如下:使用 lambda 表达式反转拼写,然后依此给单词列表排序

    >>> fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana']
    >>> sorted(fruits, key=lambda word: word[::-1])
    ['banana', 'apple', 'fig', 'raspberry', 'strawberry', 'cherry']
    >>>
    

    四、可调用的对象

    用户自定义的函数对象通常是可调用的,可以通过()运算符应用到可调用的对象,例如内置函数str

    >>>mystr = 123
    >>>str(mystr) # mystr内置函数是可调用的
    '123'
    

    那么除了它,Python中的其他对象是否可调用呢,可以使用内置的 callable() 函数。

    >>> abs, str, 13
    (<built-in function abs>, <class 'str'>, 13)
    >>> [callable(obj) for obj in (abs, str, 13)]
    [True, True, False]
    

    Python 数据模型文档列出了 7 种可调用对象。

    • 用户定义的函数:使用 def 语句或 lambda 表达式创建。
    • 内置函数:使用 C 语言(CPython)实现的函数,如 len 或 time.strftime。
    • 内置方法:使用 C 语言实现的方法,如 dict.get。
    • 方法:在类的定义体中定义的函数。
    • 类 
    • 类的实例
    • 生成器函数 :使用 yield 关键字的函数或方法。调用生成器函数返回的是生成器对象

    五、函数内省

    既然把函数作为对象看待,那么就应该具有对象一样的特性:内省
    内省是什么:内省指一种能力,可以确定对象是什么,包含何种信息,可以做什么。
    像这样使用 dir 函数可以探知factorial 具有下述属性:

    >>> dir(factorial)
    ['__annotations__', '__call__', '__class__', '__closure__', '__code__',
    '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',
    '__format__', '__ge__', '__get__', '__getattribute__', '__globals__',
    '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__',
    '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__',
    '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
    '__subclasshook__']
    
  • 相关阅读:
    HDU 2895 编辑距离
    AC自动机
    HDU 1707 简单模拟 Spring-outing Decision
    HDU 1710 二叉树的遍历 Binary Tree Traversals
    Codeforces Round #521 (Div. 3) E. Thematic Contests
    Codeforces Round #521 (Div. 3) D. Cutting Out
    Codeforces Round #515 (Div. 3) E. Binary Numbers AND Sum
    Codeforces Round #510 (Div. 2) B. Vitamins
    Codeforces Round #510 (Div. 2) D. Petya and Array(树状数组)
    Codeforces Round #506 (Div. 3) 题解
  • 原文地址:https://www.cnblogs.com/welan/p/9650209.html
Copyright © 2020-2023  润新知