高阶函数

什么是高阶函数?

高阶函数:它接收一个或多个函数作为参数, 并/或(这里是不一定,一定要注意)能够返回一个函数作为结果的函数.

filter()

过滤函数:filter(func or None, iterable):函数用于过滤序列,过滤掉不符合该函数的元素,返回由符合该函数元素组成的迭代器.

该接收两个参数,第一个为判断函数或为None,第二个为可迭代对象,序列的每个元素作为参数传递给函数进行判断,最后将返回 True 的元素放到新的迭代器中。如果选择的是None,则返回的是包含这个序列所有元素的迭代器。

例子:

def is_odd(x):return x%2==0     #这里返回值直接接判断条件和 你先if 再return True 是一样的
ret=filter(is_odd,[1,4,6,7,8,9,12,17]) #这里输入的是函数名而不是调用的函数不需要加括号。
print(ret)
print(list(ret)) #把迭代器转化为列表

结果:

<filter object at 0x000001EAB5EFC160>
[4,6,8,12]

例子二

newlist = filter(None, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print((newlist))
print(list(newlist))

结果

<filter object at 0x000002A9FA02C0F0>
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

map()

map()函数: map(func,iterable)→迭代器→ new iterable   , 和filter不同的是map中的func,接收的是一个计算式,然后它把iterable中的元素拿到计算式中进行计算,最后得到一个包含表达式结果的迭代器。


def f(x):
return x*x
r=map(f,[1,2,3,4])
a=map(str,[1,2,3,4])
print("ddd",next(a)) #含有next方法
print('aa',list(a))
 

结果:

ddd 1
aa ['2', '3', '4']

 

reduce()

reduce() 函数会对参数可迭代中的元素按照该函数进行累积(也就是先把迭代对象中的前两个元素按照该函数进行计算,算出的结果再和第三个元素按照该函数进行计算,一次类推)。

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

语法

reduce() 函数语法:

reduce(function, iterable[, initializer])

参数

  • function -- 函数,有两个参数
  • iterable -- 可迭代对象
  • initializer -- 可选,初始参数
from functools import reduce #在python3中需要导入reduce

def add(x,y): #一定要传两个参数
    return x+y



ff
=reduce(add,[1,2,4,5]) #其实就是1+2=3 3+4=7 7+5=12 print(ff)

结果:

12

  sorted

 sorted临时排序函数:sorted(iterable[, cmp[, key[, reverse]]])  把iterable中的items进行排序之后,返回一个新的列表,原来的iterable没有任何改变.ist 的 sort 方法返回的是对已经存在的列表进行操作,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。

iterable:是可迭代类型;
key:传入一个函数名,函数的参数是可迭代类型中的每一项,根据函数的返回值大小排序;
reverse:排序规则. reverse = True  降序 或者 reverse = False 升序,默认值为升序。
返回值:有序列表

 列表按照其中每一个值的绝对值降序排序

def ab(n):
if n <0:
return -n
else:
return n

li=[1,3,5,-2,6,-9]

newlist=sorted(li,key=ab,reverse=True)
print(li)
print(newlist)

结果:

[1, 3, 5, -2, 6, -9]
[-9, 6, 5, 3, -2, 1]

其他函数

1.将对象用字符串的方式表示出来有两种方法。

通常我们打印一个对象,情况为这样:

class A:
    def __init__(self):
        self.name = 1


a = A()

print(a)

#j结果:
<__main__.A object at 0x10c899668>
(1)str()用于将数值转化为易于人读的形式。print(str("我是中国人"))>>>我是中国人
class A:
    def __init__(self):
        self.name = 'hello'

    def __str__(self):
        return self.name

a = A()

print(a)

#结果:
hello


(2)repr()用于将数值转化为易于解释器读的形式输出的是字符串的官方标准。str出来的值是给人看的字符串,repr出来的值是给机器看的,括号中的任何内容出来后都是在它之上再加上一层引号。
class A:
    def __init__(self):
        self.name = 'hello'

    # def __str__(self):
    #     print("a")
    #     return self.name

    def __repr__(self):
        print("b")
        return self.name


a = A()

print(a)

#结果
hello

__repr__和__str__的区别在于,后者是在str()函数中被使用的,或在print打印一个对象时才使用

print(repr("我是中国人"))>>>"我是中国人" 。Python中出现的任何中文,虽然我们在编辑器里看到的是中文,但是背地里全是一串编码。千万不要轻易信任print!print xx给你显示出来的,
其实并不是xx的真实面貌!
2.eval()将字符串str当成有效的表达式来求值并返回计算结果. 不建议用,因为有很大的安全隐患。具体百度,它会把你的系统命令给执行了。
l="5+8"
print(eval(l))

结果:

13

3.exec函数和eval函数类似,动态执行Python代码。也就是说exec可以执行复杂的Python代码,而不像eval函数那么样只能计算一个表达式的值。,只不过eval函数只用于执行表达式求值,而exec函数主要用于执行语句块。

exec("l=5+6") #注意这里不用赋值
print(l)
11

 4.compile()编译函数:compile(source, filename, mode[, flags[, dont_inherit]])

) 将字符串类型代码进行编译。代码对象可以通过exec()或eval(),进行执行。

1. 参数source:字符串或者AST(Abstract Syntax Trees)对象。即需要动态执行的代码段。  

2. 参数 filename:代码文件名称,如果不是从文件读取代码则传递一些可辨认的值。当传入了source参数时,filename参数传入空字符即可。  

3. 参数model:指定编译代码的种类,可以指定为 ‘exec’,’eval’,’single’。当source中包含流程语句时,model应指定为‘exec’;当source中只包含一个简单的求值表达式,model应指定为‘eval’;当source中包含了交互式命令语句,model应指定为'single'。

 

code1="for i in range(0,10):print(i)"
compile1=compile(code1,"","exec")
print(exec(compile1))

结果:

0
1
2
3
4
5
6
7
8
9
None

 

4.内建函数:

list(iterable)把可迭代对象转换成列表

 tuple(iterable)把可迭代对象转换成元组

str(obj)把对象转化为字符串(对象的字符串表示法)

zip

zip()拉链函数:函数用于将每个可迭代的对象作为参数,将对象中对应的元素打包成一个个的元组,然后返回由这些元组组成的迭代器。

如果各个迭代器的元素个数不一致,则返回元组个数与最短的迭代对象相同,利用 * 号操作符,可以将元组迭代器解包为各个元组。

l1=[1,2,3]
l2=[4,5,8,3]
print(*(zip(l1,l2)))

结果:

(1, 4), (2, 5), (3, 8)

 数据函数

divmod()函数: 函数把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)。

print(divmod(3,2))

结果:

(1, 1)

min()函数:

min(iterable*[, keydefault])

min(arg1arg2*args[, key])

 函数功能为取传入的多个参数中的最小值,或者传入的可迭代对象元素中的最小值。默认数值型参数,取值小者;字符型参数,取字母表排序靠前者。还可以传入命名参数key,其为一个函数,用来指定取最小值的方法。default命名参数用来指定最小值不存在时返回的默认值。功能与max函数相反。

为啥不是高阶函数?

对于 min 函数来说,它通常不被视为高阶函数,因为它的主要目的是查找可迭代对象中的最小值,而不是接受函数作为参数或返回函数作为结果。高阶函数的定义涉及到将函数作为参数传递或返回函数,
以便实现某种功能或修改函数的行为。 虽然 min 函数具有可选的 key 参数,该参数允许你自定义比较元素的键,但这并不足以将其归类为高阶函数。高阶函数通常更为通用,它们能够接受不同类型的函数,以便实现更广泛的功能。 在 Python 中,高阶函数的示例包括 map、filter、sorted 等,它们接受函数作为参数,以实现数据转换、筛选和排序等功能。虽然 min 函数在特定情况下可以使用 key 参数来实现自定义功能,
但它的主要目的是查找最小值,而不是通用的函数装饰或转换操作。因此,通常不将 min 函数视为高阶函数

 

print(min(26,7,8,9))
# 结果
7

 

同类型之间可以进行比较

print(min([1,2],[1,3]))
[1, 2]

key参数的另外一个作用是,不同类型对象本来不能比较取最小值的,传入适当的key函数,变得可以比较能取最小值了。

print(min(1,2,'3',key = int))

结果:

1

 还有个例子

# 使用 key 参数自定义查找条件
students = [("Alice", 95), ("Bob", 82), ("Charlie", 90)]
min_student = min(students, key=lambda student: student[1])
print(min_student)  # 输出 ('Bob', 82)

# 在空列表中使用 default 参数
empty_list = []
min_value = min(empty_list, default="No values")
print(min_value)  # 输出 'No values'

 lambda

lambda函数也叫作 匿名函数,即函数没有具体的名字,出现的背景我认为是临时性创造一个匿名函数给map,filter.或reduce

比如:

正常函数这样写:

def func(x):
    return (x+1)

lambda函数这样写:

func=lambda x:x+1
print(func(1)) 

lambda函数的作用

1 用python写一些执行脚本时,可以省去定义函数的过程,让代码更简洁

2.对于一些抽象的,不会别的地方再复用的函数,有时候给函数起名字也是一个难题

3. 使用lambda在某些时候让代码更容易理解

4.临时性创造一个匿名函数给map,filter.或reduce

比如我们写一个从列表中删除0分的一个函数

f=filter(lambda x:x>0,[1,50,6,0])
print(list(f))

结果:

[1, 50, 6]

 

lambda函数的语法规则:

冒号前是参数,可以有多个,用逗号隔开,冒号后面是返回值,lambda语句其实是构造的一个函数对象. 这里你要见证一下

func=lambda x:x+1
print(func)


def f(x):
    return (x+1)
print(f)

结果:

<function <lambda> at 0x0000023C65DF1E18>
<function f at 0x0000023C65FBF488>

这儿的lambda有一个大坑

val= [(lambda n: i+n) for i in range(5)]
for i1 in val:
    print(i1(2))

结果是:

6
6
6
6
6

为什么是这样呢,为什么不是

2
3
4
5
6

把上边的lambda表达式其实是这样写:

for i in range(4):
    def f(x):
        return i*x
t=f(2)
print(t)

结果:

 6

 

上边没有达到预期的原因是lambda中的i 用的匿名函数外的全局变量,修改一下

val= [(lambda n,i=i: i+n) for i in range(5)]
for i1 in val:
    print(i1(2))

结果:

2
3
4
5
6

参考http://www.cnblogs.com/coderzh/archive/2010/04/30/python-cookbook-lambda.html

https://zhuanlan.zhihu.com/p/37063984

 

posted on 2017-11-11 12:11  程序员一学徒  阅读(347)  评论(0编辑  收藏  举报