python的lambda-map-reduce

lambda作为一个表达式,定义了一个匿名函数:lambda x:f(x),冒号左边的是入口参数,右边的是函数体,可以用函数表示:

def f(x):
	函数体
	return f(x)

举例

lambda x:x**2

他的作用等同于:

def f(x):
	return x**2

lambda单独使用:

tt=lambda x:x**2
print(tt(9))
#81

如果没有参数:

kk = lambda: 3
print(kk, type(kk), kk())

#等同于:
def func():
    return 3
print(func())

输出为:

<function <lambda> at 0x0000014E873AC268> <class 'function'> 3
3

进阶用法:

def multipliers():
    return [lambda x: i * x for i in range(4)]
def multipliers():
    # 添加了一个默认参数i=i
    return [lambda x, i=i: i * x for i in range(4)]

测试执行:

for x in multipliers():
    print(x(2))

原因分析:
第一个版本的multipliers函数创建了一个列表,其中包含4个 lambda 函数。这些函数在调用时会返回参数 x 与一个变量 i 的乘积,而 i 的值在每个 lambda 函数被调用之前都是最后一次循环迭代的结果,即 i 的值为 3。

因此,当我们调用第一个版本的multipliers函数时,每个 lambda 函数都会返回 3 倍的参数 x。例如,multipliers()[0](2) 将返回 6,因为 lambda 函数计算的结果为 3 * 2

第二个版本的multipliers函数中添加了一个默认参数 i=i,这意味着每个 lambda 函数在定义时都会将当前的 i 值绑定到它的默认参数上。这样,当我们调用 lambda 函数时,它将使用在定义时绑定到它的默认参数上的 i 值,而不是最后一次循环迭代的结果。
因此,当我们调用第二个版本的multipliers函数时,每个 lambda 函数都会使用不同的 i 值进行计算。例如,multipliers()[0](2) 将返回 0,因为 lambda 函数计算的结果为 0 * 2,而不是 6。
因此,通过为 lambda 函数添加默认参数 i=i,我们可以正确地创建一个包含多个 lambda 函数的列表,每个函数都使用不同的 i 值进行计算。这使得我们可以像期望的那样使用这些函数。

在如下两个方法中,结果都是使用终值,与预期不符

def test():
    func_list = []
    for i in range(5):
        def func():
            return i

        func_list.append(func)

    for x in func_list:
        print(x())


test()


def test2():
    lambda_list = [lambda: i for i in range(5)]
    for lambda_unit in lambda_list:
        print(lambda_unit())


test2()

如果在循环体中定义了函数/lambda并引用了循环变量,则在循环体外调用该函数时,将始终获取到该循环变量的终值,导致结果与预期不一致。
这种情况通常发生在希望延迟执行一些预定义好的函数时发生,如:提前定义一系列的操作,在某种条件下再执行这一系列自动循环生成的操作。
因此:

  1. 如果在循环内定义函数/lambda表达式并且在循环内调用,则不做限制
  2. 如果在循环内定义函数/lambda表达式并且在循环外调用,该函数/lambda表达式不应引用循环中
    定义的变量。
    lambda作为隐函数使用:
    结合map:
li=[1,2,3,4,5]
tt=map(lambda x:x**2,li)
for x in tt:
    print(x)

输出:

1
4
9
16
25

结合reduce:

from functools import reduce
li=[1,2,3,4,5]
tt=reduce(lambda x,y:x*y,li)
print(tt)

输出:

120

map和reduce是python的高阶函数:map(映射)用于把一组键值对映射成一组新的键值对,Reduce(归约)用于把一组键值对归约为一个单值
map(f,[x1,x2,x3])=[f(x1),f(x2),f(x3)],对于Iterable的每一个元素代入f函数获取返回值:

def doubl(x):
    return x*2
li=[1,2,3,4,5]
res=map(doubl,li)
print(res)
print(type(res))
for x in res:
    print(x)

输出为:

<map object at 0x000002AF26823148>
<class 'map'>
2
4
6
8
10

reduce(f,[x1,x2,x3])=f(x1,f(x2,f(x3)))

from functools import reduce
def doubl(x,y):
    return x*y
li=[1,2,3,4,5]
res=reduce(doubl,li)
print(res)
print(type(res))

输出为:

120
<class 'int'>

需要注意:python3不再支持reduce,需要从functools导入
补充:
filter 用于过滤掉序列中不符合条件的元素,返回由符合条件元素组成的新列表。
接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。

filter(function, iterable)
function 判断函数
iterable 可迭代对象

def is_odd(n):
    return n % 2 == 1
lis = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(type(lis))
for x in lis:
    print(x)
# <class 'filter'>
# 1
# 3
# 5
# 7
# 9
  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值