【Python基础知识】Python高阶函数

发布 : python培训      来源:python干货资料

2020-11-25 10:59:12

高阶函数是指接收函数为参数,或者将函数作为结果返回的函数。

(1)sorted()函数

sorted()函数用于对可迭代对象进行排序。除此之外,sorted()函数是高阶函数,可以传递给sorted()函数一个自定义的函数作为参数,这个参数的名字是key,必须以关键字参数的形式传递。sorted()函数要比较的每个值都会传入key指定名称的函数内,并根据该函数的返回值进行比较,以实现按自定义的排序方式进行排序。

例如,下面的列表中包含了一些代表动物的字符串,将它们进行排列:

  1. >>> animals = ['panda', 'lion', 'tiger', 'fox', 'elephant']
  2. >>> sorted(animals) # 未指定key参数
  3. ['elephant', 'fox', 'lion', 'panda', 'tiger']
  4. >>> sorted(animals, key=len) # 指定key参数的值为len
  5. ['fox', 'lion', 'panda', 'tiger', 'elephant']

在未指定key参数的情况下,列表按照字典顺序排序。在指定key参数的值为len的情况下,列表按照字符串的长度排序(len()函数),animals列表中的每个字符串都“输入”len()函数,再将字符串的长度作为返回值“输出”,如'fox'的长度为3,数值最小,故排在第一位,'elephant'长度为8,数值最大,故排在最后一位。注意,此处len()函数没有括号,是将函数名作为参数,如果加上括号,那么是调用函数。

再举另外一个示例,字符串的lower()方法是将字母变成小写字母,同样也可以使用str.lower()将lower()方法作为函数使用,下面两种方式是等价的:

  1. >>> 'P'.lower()
  2. 'p'
  3. >>> str.lower('P')
  4. 'p'

知道这个知识后,就能将str.lower()函数用在字符串排序中了。下面的示例中,将含有字母的列表排序:

  1. >>> letters = ['a', 'Y', 'z', 'B']
  2. >>> sorted(letters) # 未指定排序方式,按默认方式排序,大写字母总在小写字母前面
  3. ['B', 'Y', 'a', 'z']
  4. >>> letters = ['a', 'Y', 'z', 'B']
  5. >>> sorted(letters, key=str.lower) # 将所有字母全部变为小写字母再排序
  6. ['a', 'B', 'Y', 'z']

除了使用内建函数之外,当然也可以使用自定义的函数来指定排序规则。仍然使用前面的animals列表,这次将'panda'排在第一位,剩下的动物依旧按照字符串的长度排序。

  1. >>> animals = ['panda', 'lion', 'tiger', 'fox', 'elephant']
  2. >>> def panda_first(animal):
  3. ... if animal == 'panda': # 如果是'panda',返回0,使其排在第一位
  4. ... return 0
  5. ... else: # 如果是其他动物,那么返回它的长度
  6. ... return len(animal)
  7. ...
  8. >>> sorted(animals, key=panda_first)
  9. ['panda', 'fox', 'lion', 'tiger', 'elephant']

然而,通常为了给key参数提供一个值而编写一个普通函数是不太值得的,往往使用匿名函数即可:

  1. >>> animals = ['panda', 'lion', 'tiger', 'fox', 'elephant']
  2. >>> sorted(animals, key=lambda animal: 0 if animal == 'panda' else len(animal))
  3. ['panda', 'fox', 'lion', 'tiger', 'elephant']

这个匿名函数看起来有些复杂,它的参数是animal,表达式是一个三目表达式:如果animal的值是'panda',返回0,否则返回animal的长度。使用匿名函数可以在一行内方便地将列表排列成指定顺序。

使用sorted()函数和匿名函数还可以用来给字典排序。例如,将下面的水果字典(将字典的值想象为水果数量)按照水果数量从大到小的顺序排序:

  1. >>> fruits = {'apple': 10, 'banana': 42, 'orange': 5, 'mango': 18}
  2. >>> sorted(fruits.items(), key=lambda item: item[1]) #比较字典的第2项
  3. [('orange', 5), ('apple', 10), ('mango', 18), ('banana', 42)]

由于sorted()函数只能对可迭代对象进行排序,而字典的items()方法返回的值可以迭代,因此,可以使用items()方法进行迭代。

(2)max()函数和min()函数

max()函数和min()函数也是高阶函数,与sorted()函数的相似之处在于,它们也要经过比较才能返回值(可以理解为sorted()排序后的最大值和最小值)。max()函数和min()函数也有key参数,作用机制与sorted()函数一致。

例如,下面的字典中存储着各个同学的分数,使用max()找到分数最高的同学:

  1. >>> grade = {'小明': 72, '梅梅': 81, '丽丽': 58}
  2. >>> max(grade.items(), key=lambda item: item[1])
  3. ('梅梅', 81)

假设老师给小明加了10分,那么需要改动匿名函数:

  1. >>> grade = {'小明': 72, '梅梅': 81, '丽丽': 58}
  2. >>> max(grade.items(), key=lambda item: item[1] + 10 if item[0] == '小明' else item[1])
  3. ('小明', 72)

min()函数与max()函数是相似的,只是min()函数返回的是最小值:

  1. >>> numbers = [15, 400, 2800, 821, 42, 1000, 99]
  2. >>> min(numbers)
  3. 15

下面将用自定义的函数作为key参数的值,这个参数返回一个数字各个位相加的和(由于这个函数稍微有些复杂,因此,建议使用def关键字定义函数):

  1. >>> def sum_digit(num):
  2. ... sum = 0
  3. ... while num:
  4. ... sum += num % 10
  5. ... num = num // 10
  6. ... return sum
  7. >>> # 下面简单测试一下这个函数的正确性
  8. >>> sum_digit(46) # 4和6相加为10
  9. 10
  10. >>> sum_digit(99) # 9和9相加为18
  11. 18
  12. >>> sum_digit(1000) # 1和0相加为1
  13. 1
  14. >>> # 下面使用这个函数作为key参数的值
  15. >>> numbers = [15, 400, 2800, 821, 42, 1000, 99]
  16. >>> min(numbers, key=sum_digit)
  17. 1000

(3)map()函数

map()函数的语法格式如下:

map(func, seq)

map()函数中有两个参数,第一个参数是函数func,第二个参数是序列seq。map()是一个映射函数,根据提供的函数对指定的序列做映射。map()函数是以序列seq中的每一项作为参数依次调用函数func,返回包含每次函数func返回值的map对象。

map()函数的第一个参数函数func可以是内建函数,也可以是自定义函数,甚至可以是匿名函数;第二个参数序列seq可以是列表、元组、字符串等。

例如,map()函数的第一个参数是内建函数,第二个参数是列表:

  1. >>> alist = [1, -2, -3]
  2. >>> print(list(map(abs, alist)))
  3. [1, 2, 3]

在上述程序中,abs是绝对值函数。由于map()函数的返回值是map对象,因此,使用list()方法将其转换成列表。

例如,map()函数的第一个参数是自定义函数,第二个参数是元组:

  1. >>> def f(x):
  2. ... return x ** 2
  3. ...
  4. >>> print(list(map(f, (2, 4, 7, 10))))
  5. [4, 16, 49, 100]

上述程序也可以改成匿名函数的形式:

  1. >>> print(list(map(lambda x: x ** 2, (2, 4, 7, 10))))
  2. [4, 16, 49, 100]

(4)filter()函数

filter()函数的语法格式如下:

filter(func, seq)

filter()是一个过滤器函数,用于过滤掉序列中不符合条件的项。filter()函数以序列seq中的每一项作为参数依次调用函数func进行判断,函数func返回True或False,将返回值为True的项放进filter对象中返回。

例如,过滤掉列表[7,10,13,16,17,19,21,22,26,28,29]中的奇数项,只输出偶数项:

  1. >>> def fun(x):
  2. ... if x % 2 == 0:
  3. ... return x
  4. ...
  5. >>> alist = [7, 10, 13, 16, 17, 19, 21, 22, 26, 28, 29]
  6. >>> print(list(filter(fun, alist)))
  7. [10, 16, 22, 26, 28]

(5)reduce()函数

reduce()函数的语法格式如下:

reduce(func, seq[, init])

其中,init是一个可选参数,表示初始值。注意,在使用reduce()函数前要导入from functools import reduce。

reduce()是一个累计函数,其实现原理:如果存在init参数,即有初始值,那么将初始值和序列seq的第1项作为参数传值给函数func进行运算,再将返回值与序列seq的第2项作为参数传值给函数func进行运算……这样依次将返回值与序列seq的下一项作为参数传值给函数func进行运算,直到序列最后一项运算完为止,返回最终的运算结果。如果不存在init参数,那么将序列seq的第1项和第2项作为参数传值给函数func进行运算,再将返回值与序列seq的第3项作为参数传值给函数func进行运算……这样依次将返回值与序列seq的下一项作为参数传值给函数func进行运算,直到序列最后一项运算完为止,返回最终的运算结果。

例如,初始值为100,对列表[1,2,3]使用reduce()函数进行累乘:

  1. >>> from functools import reduce
  2. >>> alist = [1, 2, 3]
  3. >>> def fun(x,y):
  4. ... return x * y
  5. ...
  6. >>> print(reduce(fun, alist, 100))
  7. 600

上述程序的功能等价于如下代码:

  1. >>> alist = [1,2,3]
  2. >>> num = 100
  3. >>> sum = alist[0] * num
  4. >>> for i in range(len(alist) -1):
  5. ... sum *= alist[i+1]
  6. ...
  7. >>> print(sum)
  8. 600

THE END  

声明:本站稿件版权均属中公教育优就业所有,未经许可不得擅自转载。

领取零基础自学IT资源

涉及方向有Java、Web前端、UI设计、软件测试、python等科目,内容包含学习路线、视频、源码等

点击申请领取资料

点击查看资料详情 

收起 


 相关推荐

问题解答专区
返回顶部