乐趣区

关于python:python内置的几个高阶函数

python 内置的几个高阶函数

python 中所有皆能够为对象;而高阶函数的含意为其传入的参数中蕴含函数对象,接管函数对象为参数的函数为高阶函数。python 中有几个内置的高阶函数,包含 map(),sorted(),filter(); 早前的 python 版本中还有内置的 reduce(), 当初该函数被放在 functools 模块中了。

map()函数

在之前的文章中曾经具体讲过了,详情参考 https://blog.csdn.net/Always_…

补充的一点:

对于大部分 map()应用的场景,都曾经能够用列表推导式简便的代替,对于多个参数传入的情景,个别须要转换为下标的模式:

>>>a=[1,2,3]
>>>b=[10,20,30]
>>>[a[i]+b[i] for i in range(3)]
[11, 22, 33]

sorted()函数

提到 sorted()函数必须要和 sort()函数辨别:

  • sorted()函数是内置函数,接管一个可迭代对象,对所有可迭代对象均可依照肯定规定进行排序,会返回一个新的可迭代对象。
  • sort()函数是 List 对象的一个办法,间接批改原 list,返回 None
>>>a=[2,3,1]
>>>b=sorted(a)# 返回新对象
>>>b
[1, 2, 3]
>>>a# 原对象不扭转
[2, 3, 1]

>>>a=[2,3,1]
>>>b=a.sort()# 返回 None
>>>a
[1, 2, 3]# 扭转原对象
>>>b

>>>sort(a)# 内置办法只有 sorted()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'sort' is not defined

而 sorted()函数自身十分有用,尤其和 key 联合起来。之所以 sorted 是高阶函数,因为其外部参数能够接管一个函数对象。

>>>a=[1,-2,3,-1,10,-20]
>>>sorted(a)# 默认从小排到大
[-20, -2, -1, 1, 3, 10]
>>>sorted(a,reverse=True)# 从大排到小
[10, 3, 1, -1, -2, -20]
>>>sorted(a,key=lambda x:x**2)#key 传入一个函数对象,通过每个数的平方来排序
[1, -1, -2, 3, 10, -20]

对于多维列表排序:

>>>a=[[2,3,1],[10,-1,3],[-1,20,2]]
>>>sorted(a,key=lambda x:x[1])# 依据每行第 2 个数进行排序
[[10, -1, 3], [2, 3, 1], [-1, 20, 2]]

对于字符串排序:

>>>a=['hacca','de','djnhg']
>>>sorted(a,key=lambda x:x[-1])
['hacca', 'de', 'djnhg']

对于自定义的对象排序:

class A:
    def __init__(self,a,b):
        self.a=a
        self.b=b
    def __repr__(self):
        return '%s_%s_%s'%(self.__class__.__name__,self.a,self.b)
>>>x=[A(1,2),A(-1,3),A(-10,1)]
>>>sorted(x,key=lambda x:x.a)
[A_-10_1, A_-1_3, A_1_2]

总之,sorted()函数配合 key 应用 lambda 匿名函数十分好用。

filter()函数

filter()顾名思义,为一个过滤函数;接管一个函数和一个可迭代对象,将函数顺次作用在该可迭代对象上,其中函数每次必须返回 True 或者 False. 最初将返回为 True 的元素保留下来。

>>>a=[1,2,3,4,5]
>>>def func(x):
>>>    return x%2==0
>>>list(filter(func,a))#a 中的 2 和 4 传入函数时返回为 True, 因而最初只剩下 2 和 4
[2, 4]

>>>[x for x in [1,2,3,4,5] if x%2==0]# 也能够用列表推到式实现
[2, 4]

举一个绝对比较复杂的例子。如何认定学生是否偏科呢?合乎如下其中一条的学生,将被视为偏科:

  • 有 2 科问题在 80 分以上,有一科在 60 分以下。
  • 有 1 科问题在 90 分以上,另外 2 科问题都在 60 分以下。
  • 有 1 科问题在 90 分以上,但三科的平均分在 70 分以下。
scores = [("Emma", 89 , 90 , 59),
      ("Edith", 99 , 49 , 59),
      ("Sophia", 99 , 60 , 20),
      ("May", 40 , 94 , 59),
      ("Ashley", 89 , 90 , 59),
      ("Arny", 89 , 90, 69),
      ("Lucy", 79 , 90 , 59),
      ("Gloria", 85 , 90 , 59),
      ("Abby", 89 , 91 , 90)]
def handle_filter(a):
    s = sorted(a[1:]) #对三科问题进行排序
    #有 2 科问题在 80 分以上,并且有 1 科在 60 分以下的
    if s[-2] > 80 and s[0] < 60 :
        return True
    #有 1 科问题在 90 分以上,另外 2 科问题都在 60 分以下
    if s[-1] > 90 and s[1] < 60 :
        return True
    if s[-2] > 80 and sum(s)/len(s) < 60:
        #有 1 科问题在 90 分以上,且 3 科的平均分在 70 分以下
        return True
    return False
>>>list(filter(handle_filter, scores))
[('Emma', 89, 90, 59), ('Edith', 99, 49, 59), ('May', 40, 94, 59), ('Ashley', 89, 90, 59), ('Gloria', 85, 90, 59)]

能够看到,对于这样规定比较复杂的过滤,用列表推导式会十分较为麻烦且代码易读性会较差了,这个时候用 filter 还是更为难看的。但都比 for 循环要来得好。

reduce()函数

python3 中 reduce 都曾经在 functools 模块中,语法为:

reduce(function, sequence[, initial]) -> value

reduce 函数承受一个 function 和一串 sequence,并返回繁多的值,以如下形式计算:
1. 初始,function 被调用,并传入 sequence 的前两个 items,计算失去 result 并返回
2.function 持续被调用,并传入上一步中的 result,和 sequence 种下一个 item,计算失去 result 并返回。始终反复这个操作,直到 sequence 都被遍历完,返回最终后果。
留神. 当 initial 值被指定时,传入 step1 中的两个参数别离是 initial 值和 sequence 的第一个 items。reduce()最多只能承受三个参数,func,sequence,initial。

>>>reduce(lambda a,b:a+b,[1,2,3,4,5])# 传入的第一个值为 1
15
>>>reduce(lambda a,b:a+b,[1,2,3,4,5],100)# 传入的第一个初始值为 100
115

reduce 这个性能齐全能够用 sum 来代替了。

退出移动版