Python 函数式编程,没什么废话,直接看用法和代码

简介: lambda 这个关键词在很多语言中都存在。简单地说,它可以实现函数创建的功能。

lambda


lambda 这个关键词在很多语言中都存在。简单地说,它可以实现函数创建的功能。

如下便是 lambda 的两种使用方式。


func1 = lambda : <expression()>
func2 = lambda x : <expression(x)>
func3 = lambda x,y : <expression(x,y)>
复制代码


在第一条语句中,采用 lambda 创建了一个无参的函数 func1。这和下面采用 def创建函数的效果是相同的。


def func1():
    <expression()>
复制代码


在第二条和第三条语句中,分别采用 lambda 创建了需要传入 1 个参数的函数 func2,以及传入 2 个参数的函数 func3。这和下面采用def创建函数的效果是相同的。


def func2(x):
    <expression(x)>
def func3(x,y):
    <expression(x,y)>
复制代码


需要注意的是,调用 func1 的时候,虽然不需要传入参数,但是必须要带有括号(),否则返回的只是函数的定义,而非函数执行的结果。


>>> func = lambda : 123
>>> func
<function <lambda> at 0x100f4e1b8>
>>> func()
123
复制代码


另外,虽然在上面例子中都将 lambda 创建的函数赋值给了一个函数名,但这并不是必须的。从下面的例子中大家可以看到,很多时候我们都是直接调用 lambda 创建的函数,而并没有命名一个函数,这也是我们常听说的匿名函数的由来。


map()


map()函数的常见调用形式如下所示:


map(func, iterable)
复制代码


map()需要两个必填参数,第一个参数是一个函数名,第二个参数是一个可迭代的对象,如列表、元组等。

map()实现的功能很简单,就是将第二个参数(iterable)中的每一个元素分别传给第一个参数(func),依次执行函数得到结果,并将结果组成一个新的list对象后进行返回。返回结果永远都是一个list

简单示例如下:


>>> double_func = lambda s : s * 2
>>> map(double_func, [1,2,3,4,5])
[2, 4, 6, 8, 10]
复制代码


除了传入一个可迭代对象这种常见的模式外,map()还支持传入多个可迭代对象。


map(func, iterable1, iterable2)
复制代码


在传入多个可迭代对象的情况下,map()会依次从所有可迭代对象中依次取一个元素,组成一个元组列表,然后将元组依次传给 func;若可迭代对象的长度不一致,则会以 None 进行补上。

通过以下示例应该就比较容易理解。


>>> plus = lambda x,y : (x or 0) + (y or 0)
>>> map(plus, [1,2,3], [4,5,6])
[5, 7, 9]
>>> map(plus, [1,2,3,4], [4,5,6])
[5, 7, 9, 4]
>>> map(plus, [1,2,3], [4,5,6,7])
[5, 7, 9, 7]
复制代码


在上面的例子中,之所以采用x or 0的形式,是为了防止None + int出现异常。

需要注意的是,可迭代对象的个数应该与 func 的参数个数一致,否则就会出现异常,因为传参个数与函数参数个数不一致了,这个应该比较好理解。


>>> plus = lambda x,y : x + y
>>> map(plus, [1,2,3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: <lambda>() takes exactly 2 arguments (1 given)
复制代码


另外,map()还存在一种特殊情况,就是 func 为 None。这个时候,map()仍然是从所有可迭代对象中依次取一个元素,组成一个元组列表,然后将这个元组列表作为结果进行返回。


>>> map(None, [1,2,3,4])
[1, 2, 3, 4]
>>> map(None, [1,2,3,4], [5,6,7,8])
[(1, 5), (2, 6), (3, 7), (4, 8)]
>>> map(None, [1,2,3,4], [5,6,7])
[(1, 5), (2, 6), (3, 7), (4, None)]
>>> map(None, [1,2,3,4], [6,7,8,9], [11,12])
[(1, 6, 11), (2, 7, 12), (3, 8, None), (4, 9, None)]
复制代码


reduce()


reduce()函数的调用形式如下所示:


reduce(func, iterable[, initializer])
复制代码


reduce()函数的功能是对可迭代对象(iterable)中的元素从左到右进行累计运算,最终得到一个数值。第三个参数 initializer 是初始数值,可以空置,空置为 None 时就从可迭代对象(iterable)的第二个元素开始,并将第一个元素作为之前的结果。

文字描述可能不大清楚,看下reduce()的源码应该就比较清晰了。


def reduce(function, iterable, initializer=None):
    it = iter(iterable)
    if initializer is None:
        try:
            initializer = next(it)
        except StopIteration:
            raise TypeError('reduce() of empty sequence with no initial value')
    accum_value = initializer
    for x in it:
        accum_value = function(accum_value, x)
    return accum_value
复制代码


再加上如下示例,对reduce()的功能应该就能掌握了。


>>> plus = lambda x, y : x + y
>>> reduce(plus, [1,2,3,4,5])
15
>>> reduce(plus, [1,2,3,4,5], 10)
25
复制代码


filter()


filter()函数的调用形式如下:


filter(func, iterable)
复制代码


filter()有且仅有两个参数,第一个参数是一个函数名,第二个参数是一个可迭代的对象,如列表、元组等。

filter()函数的调用形式与map()比较相近,都是将第二个参数(iterable)中的每一个元素分别传给第一个参数(func),依次执行函数得到结果;差异在于,filter()会判断每次执行结果的bool值,并只将bool值为true的筛选出来,组成一个新的列表并进行返回。


>>> mode2 = lambda x : x % 2
>>> filter(mode2, [1,2,3,4,5,6,7,8,9,10])
[1, 3, 5, 7, 9]
复制代码


zip()


zip()函数的调用形式如下:


zip([iterable, ...])
复制代码


zip()函数接收一个或多个可迭代对象,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。


>>> zip([1, 2, 3], ["a", "b", "c"])
[(1, 'a'), (2, 'b'), (3, 'c')]
>>> dict(zip([1, 2, 3], ["a", "b", "c"]))
{1: 'a', 2: 'b', 3: 'c'}
>>> dict(zip([1, 2, 3], ["a", "b"]))
{1: 'a', 2: 'b'}
复制代码


打包元组个数与最短列表个数一致。


enumerate()


enumerate()函数的调用形式如下:


enumerate(iterable, [start=0])
复制代码


enumerate()函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。


>>> enumerate(['Spring', 'Summer', 'Fall', 'Winter'])
<enumerate object at 0x1031780>
>>> list(enumerate(['Spring', 'Summer', 'Fall', 'Winter']))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
复制代码


all()、any()


all()any()函数的调用形式如下:


all(iterable)
any(iterable)
复制代码


这两个函数比较简单,即判定一个可迭代对象是否全为 True 或者有为 True 的。


>>> all([0, 1, 2])
False
>>> any([0, 1, 2])
True


目录
相关文章
|
5天前
|
数据处理 Python
从零开始学迭代器生成器:打造高效、易读的Python代码
从零开始学迭代器生成器:打造高效、易读的Python代码
|
6天前
|
机器学习/深度学习 算法 索引
Python常用极简代码
Python常用极简代码
28 5
|
6天前
|
Python
Python实用案例代码详解
Python实用案例代码详解
13 2
|
1天前
|
缓存 监控 程序员
Python中的装饰器是一种特殊类型的声明,它允许程序员在不修改原有函数或类代码的基础上,通过在函数定义前添加额外的逻辑来增强或修改其行为。
【6月更文挑战第30天】Python装饰器是无侵入性地增强函数行为的工具,它们是接收函数并返回新函数的可调用对象。通过`@decorator`语法,可以在不修改原函数代码的情况下,添加如日志、性能监控等功能。装饰器促进代码复用、模块化,并保持源代码整洁。例如,`timer_decorator`能测量函数运行时间,展示其灵活性。
8 0
|
2天前
|
算法 搜索推荐 开发者
优化Python代码执行效率的技巧与实践
提升Python代码执行效率是开发过程中的关键挑战之一。本文探讨了几种有效的优化策略,包括算法选择、数据结构优化以及代码优化技巧,帮助开发者在实际项目中提升程序性能和响应速度。
|
3天前
|
Python
python之requests基础用法
python之requests基础用法
|
3天前
|
测试技术
Appium+python自动化(三十九)-Appium自动化测试框架综合实践 - 代码实现(超详解)
Appium+python自动化(三十九)-Appium自动化测试框架综合实践 - 代码实现(超详解)
|
4天前
|
程序员 API 计算机视觉
技术经验解读:【python自动化】02.pywin32库自动操作键鼠(保姆级代码注释)
技术经验解读:【python自动化】02.pywin32库自动操作键鼠(保姆级代码注释)
|
5天前
|
人工智能 数据挖掘 大数据
538个代码示例!麻省理工教授的Python程序设计+人工智能案例实践
Python简单易学,且提供了丰富的第三方库,可以用较少的代码完成较多的工作,使开发者能够专注于如何解决问题而只花较少的时间去考虑如何编程。 此外,Python还具有免费开源、跨平台、面向对象、胶水语言等优点,在系统编程、图形界面开发、科学计算、Web开发、数据分析、人工智能等方面有广泛应用。 尤其是在数据分析和人工智能方面,Python已成为最受开发者欢迎的编程语言之一,不仅大量计算机专业人员选择使用Python进行快速开发,许多非计算机专业人员也纷纷选择Python语言来解决专业问题。 由于Python应用广泛,关于Python的参考书目前已经有很多,但将Python编程与数据分析、人工智
|
6天前
|
Python
python 代码脚本汇编
python 代码脚本汇编
16 0