匿名函数与常用内置函数

初识匿名函数

什么是匿名函数

  匿名函数就是没有函数名的函数...

为什么要有匿名函数

  匿名函数实际上最早是出现于纯函数式编程语言中,其中匿名函数lambda是比较成功的例子,故Python也对此进行了引入。实际上匿名函数的作用就是在不丧失代码可读性的前提下为精简代码提供的一种方式。

怎么使用匿名函数

  函数的使用都是先定义后使用,不管是有名函数还是匿名函数都逃离不出这个范畴。

"""
匿名函数的定义语法:
    lambda 形参1,形参2... : 返回值 ...
"""

lambda x,y:x+y

匿名函数的调用

匿名也可以有名

# ==== 匿名函数赋值 ====

add1 = lambda x,y:x+y # 匿名函数也可以起名,开辟内存空间后用变量名指向其内存地址即可。
def add2(x,y):
    return x+y

res1 = add1(1,2)
res2 = add2(1,2)

print(res1)
print(res2)

# ==== 执行结果 ==== Ps:匿名函数并不推荐这样使用,匿名函数的精髓在于匿名二字...
"""
3
3
"""

匿名函数自执行与自销毁

# ==== 匿名函数自执行与自销毁 ====

res = (lambda x,y:x+y)(1,2) # 匿名函数自身套上括号用于与调用的()相区分。res接收的就是返回值,这种也叫自执行函数,用一次就没用了
print(res) # 由于res接收的只是匿名函数的返回值,所以该匿名函数并没有任何变量值指向,
# 根据垃圾回收机制的引用计数机制。该匿名函数会被垃圾回收机制执行清理操作。
# ==== 执行结果 ==== Ps:并不推荐这样做。匿名函数的正确打开方式不是这样子的...
"""
3
"""

与内置函数的搭配使用

# 求出下列人员薪水最大值

salaries={
    'siry':3000,
    'tom':7000,
    'lili':10000,
    'jack':2000
}

def func(k):
    return salaries[k]

res1 = max(salaries,key=func) # 这里只是稍微看一下。具体的max的用法会在下面讲到
print(res1)

res2 = max(salaries,key=lambda k:salaries[k])
print(res2)


# ==== 执行结果 ==== Ps:与其他的内置函数搭配才是lambda匿名函数的的正确打开方式...
"""
lili
lili
"""

常用内置函数介绍

max与min函数

  第一参数:传入一个可迭代对象,默认比较每一个循环到的值本身。

  第二参数(key):传入函数,指定比较方式。

  功能:max返回可迭代对象中的最大值,min返回可迭代对象中的最小值。

# ==== max()与min()的普通比较方式 ====
# 求出下列人员薪水最大值

salaries={
    'siry':3000,
    'tom':7000,
    'lili':10000,
    'jack':2000
}

res = max(salaries) # 如果传入字典,默认的只会比较key,key都是字符串,而字符串的比较方式为ASCII码。
print(res)

# ==== 执行结果 ==== 
"""
tom
"""
# ==== max()与min()的自定义比较方式 ====
# 求出下列人员薪水最大值

salaries={
    'siry':3000,
    'tom':7000,
    'lili':10000,
    'jack':2000
}

def func(k):
    return salaries[k]

res1 = max(salaries,key=func) # 如果传入的是一个有名函数则不需要带括号。它会自动运行并传入参数 --> func(每次的迭代变量..)
print(res1)

res2 = max(salaries,key=lambda k:salaries[k]) # lambda .. 由于返回的都是字典中的value,所以按照int类型进行比较。
print(res2)


# ==== 执行结果 ==== Ps:与其他的内置函数搭配才是lambda匿名函数的的正确打开方式...
"""
lili
lili
"""

map函数

  第一参数:函数

  第二参数:可迭代对象

  功能:map函数会将可迭代对象中的值依次传入第一参数的函数中,对其挨个挨个做操作...

# ==== map()的使用 ===
# 得出一个新列表,其中每个元素在其旧列表的基础上 + 10
from collections.abc import Generator
old_li = [10,20,30,40,50]

map_res = map(lambda x:x+10,old_li) # map函数返回的是一个迭代器(并非生成器)。
print(map_res)
print(isinstance(map_res,Generator)) # False,可以看出并非一个生成器

new_li = list(map_res) # 将map迭代器转换为list类型。(底层原理也是依次迭代然后append至新列表中)
print(new_li)

# ==== 执行结果 ==== Ps:与其他的内置函数搭配才是lambda匿名函数的的正确打开方式...
"""
<map object at 0x0000011B88C791C0>
False
[20, 30, 40, 50, 60]
"""

filter函数

  第一参数:函数

  第二参数:可迭代对象

  功能:filter函数会将可迭代对象中的值依次传入第一参数的函数中,得出一个布尔值结果,如果是True则保留至filter迭代器中,如果是False则不保留,说白了就是做一个过滤操作,真的留下,假的不留...

# ==== filter()的使用 ====
# 在老列表的基础上进行操作得出一个新列表,新列表中的元素必须小于3...
from collections.abc import Generator
old_li = [1,2,3,4,5]

filter_res = filter(lambda x:x < 3,old_li) # filter函数返回的是一个迭代器(并非生成器)。
print(filter_res)
print(isinstance(filter_res,Generator)) # False,可以看出并非一个生成器

new_li = list(filter_res) # 将filter迭代器转换为list类型。(底层原理也是依次迭代然后append至新列表中)
print(new_li)

# ==== 执行结果 ==== Ps:与其他的内置函数搭配才是lambda匿名函数的的正确打开方式...
"""
<map object at 0x0000011B88C791C0>
False
[1, 2]
"""

reduce函数

  第一参数:函数

  第二参数:可迭代对象

  第三参数:初始值

  功能:reduce函数会将可迭代对象中的值依次传入第一参数的函数中,第一参数函数会接收两个参数,用于做累加,累乘等操作...

  注意:在Python3中reduce函数已移除内置函数范畴。

# ==== reduce()的基本使用 ====
from functools import reduce  # 做累加,累乘等操作用reduce函数再合适不过了,但是需要导入该模块。

# 求出下面range对象中的结果...

li = range(1, 101)  # 就是 1-100


reduce_res = reduce(lambda x, y: x+y, li)  # reduce函数将直接返回一个结果。
# reduce_res = reduce(lambda x,y:x+y,li,100) # 第三参数是100,就在原有的结果上加上100,结果为 5150。
print(reduce_res)

# ==== 执行结果 ==== Ps:与其他的内置函数搭配才是lambda匿名函数的的正确打开方式...

"""
5050
"""

  我在学习JavaScript的时候才了解到reduce的原理,以前一直觉得它挺鸡肋的才导致被移除了内置函数。

  但是后来发现这玩意儿是真的强。

# ==== reduce()的原理 两参数 ====

from functools import reduce

li = [1, 5, 10]
count = 1

# 当第一次进来时,如果没有第三个参数。那么v1就是可迭代对象中的第一个值,v2就是可迭代对象中的第二个值
# 以后进来,v1就是上次函数运行的返回值,v2是可迭代对象中的下一个值。


def func(v1, v2):
    global count
    print("这是第{0}次进来,v1的值是{1}".format(count, v1))
    print("这是第{0}次进来,v2的值是{1}".format(count, v2))
    count += 1
    return v1+v2


reduce(func, li)

"""
这是第1次进来,v1的值是1
这是第1次进来,v2的值是5
这是第2次进来,v1的值是6
这是第2次进来,v2的值是10
"""
# ==== reduce()的原理 三参数 ===-

from functools import reduce

li = [1, 5, 10]
count = 1

# 当第一次进来时,如果有第三个参数。那么v1就是第三个参数,v2就是可迭代对象中的第一个值
# 以后进来,v1就是上次函数运行的返回值,v2是可迭代对象中的下一个值。


def func(v1, v2):
    global count
    print("这是第{0}次进来,v1的值是{1}".format(count, v1))
    print("这是第{0}次进来,v2的值是{1}".format(count, v2))
    count += 1
    return v1+v2


reduce(func, li, 1000)

"""
这是第1次进来,v1的值是1000
这是第1次进来,v2的值是1
这是第2次进来,v1的值是1001
这是第2次进来,v2的值是5
这是第3次进来,v1的值是1006
这是第3次进来,v2的值是10
"""
# ==== reduce()应用 寻求最大值 ====

from functools import reduce

li = [1, 5, 10, 100, 399, 29]


def func(v1, v2):
    return v1 if v1 > v2 else v2


max_value = reduce(func, li)
print(max_value)

"""
399
"""

sorted函数

  第一参数:可迭代对象

  第二参数key:传入函数,指定比较方式

  第三参数reverse:布尔值,默认False,是否进行翻转。(False时为从小到大排列,True时变为从大到小进行排列)

  功能:会将一个可迭代对象传入,依次比较大小后生成一个同类型的由小到大排列的可迭代对象。

# ==== sorted()的使用 ====
# 需求,按照工资从大到小的排列顺序来进行排序

salaries={
    'siry':3000,
    'tom':7000,
    'lili':10000,
    'jack':2000
}

res = sorted(salaries,key=lambda k:salaries[k],reverse=True) # 如不指定key,则按照名字直接字符串比较大小的方式,如不指定reverse则默认按照从小到大排列顺序
print(res)

# ==== 执行结果 ===
"""
['lili', 'tom', 'siry', 'jack']
"""

Python2与Python3的区别

  Python2中的mapfilter返回的都是一个list类型,而reduce则不需要导入functools

>>> res = map(lambda x:x + 10,range(1,11))
>>> res
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
>>> res = filter(lambda x:x > 5,range(1,11))
>>> res
[6, 7, 8, 9, 10]
>>> res = reduce(lambda x,y:x+y,range(1,101)) # 并没有导入functools..
>>> res
5050
>>>
posted @ 2020-05-21 01:49  云崖先生  阅读(239)  评论(1编辑  收藏  举报