肥宅钓鱼网
当前位置: 首页 钓鱼百科

python函数基本常识(Python函数式编程看这一篇就够了)

时间:2023-07-25 作者: 小编 阅读量: 1 栏目名: 钓鱼百科

头等函数在Python中,函数是「头等公民」。也就是说,函数与其他数据类型处于平等地位。这是通过__call__方法实现的。当int是待执行步骤的简写时,这就会派上用场。接受函数作为输入或返回函数的函数叫做高阶函数,它是函数式编程的重要组成部分。高阶函数具备强大的能力。这就是高阶函数存在的意义。我们可以在Python中使用lambda关键字来定义此类函数。

机器之心、Python 编程时光

本文对 Python 中的函数式编程技术进行了简单的入门介绍。

头等函数

在 Python 中,函数是「头等公民」(first-class)。也就是说,函数与其他数据类型(如 int)处于平等地位。

因而,我们可以将函数赋值给变量,也可以将其作为参数传入其他函数,将它们存储在其他数据结构(如 dicts)中,并将它们作为其他函数的返回值。

把函数作为对象

由于其他数据类型(如 string、list 和 int)都是对象,那么函数也是 Python 中的对象。我们来看示例函数 foo,它将自己的名称打印出来:

def foo:print("foo")

由于函数是对象,因此我们可以将函数 foo 赋值给任意变量,然后调用该变量。例如,我们可以将函数赋值给变量 bar:

bar = foobar#will print "foo" to the console

语句 bar = foo 将函数 foo 引用的对象赋值给变量 bar。

把对象作为函数

当对象可调用时(callable),它们与函数一样,如 object。这是通过 __call__ 方法实现的。

示例如下:

class Greeter:def __init__(self, greeting):self.greeting = greetingdef __call__(self, name):return self.greeting" "name

每一次配置 Greeter 类的对象时,我们都会创建一个新的对象,即打招呼时可以喊的新名字。如下所示:

morning = Greeter("good morning") #creates the callable objectmorning("john") # calling the object#prints "good morning john" to the console

我们可以调用 morning 对象的原因在于,我们已经在类定义中使用了 __call__ 方法。为了检查对象是否可调用,我们使用内置函数 callable:

callable(morning) #truecallable(145) #false. int is not callable.

数据结构内的函数

函数和其他对象一样,可以存储在数据结构内部。例如,我们可以创建 int to func 的字典。当 int 是待执行步骤的简写时,这就会派上用场。

# store in dictionarymapping = {0 : foo,1 : bar}x = input #get integer value from usermapping[x] #call the func returned by dictionary access

类似地,函数也可以存储在多种其他数据结构中。

把函数作为参数和返回值

函数还可以作为其他函数的参数和返回值。接受函数作为输入或返回函数的函数叫做高阶函数,它是函数式编程的重要组成部分。

高阶函数具备强大的能力。就像《Eloquent JavaScript》中解释的那样:

「高阶函数允许我们对动作执行抽象,而不只是抽象数值。」

我们来看一个例子。假设我们想对一个项目列表(list of items)执行迭代,并将其顺序打印出来。我们可以轻松构建一个 iterate 函数:

def iterate(list_of_items):for item in list_of_items:print(item)

看起来很酷吧,但这只不过是一级抽象而已。如果我们想在对列表执行迭代时进行打印以外的其他操作要怎么做呢?

这就是高阶函数存在的意义。我们可以创建函数 iterate_custom,待执行迭代的列表和要对每个项应用的函数都是 iterate_custom 函数的输入:

def iterate_custom(list_of_items, custom_func):for item in list_of_items:custom_func(item)

这看起来微不足道,但其实非常强大。

我们已经把抽象的级别提高了一层,使代码具备更强的可重用性。现在,我们不仅可以在打印列表时调用该函数,还可以对涉及序列迭代的列表执行任意操作。

函数还能被返回,从而使事情变得更加简单。就像我们在 dict 中存储函数一样,我们还可以将函数作为控制语句,来决定适合的函数。例如:

def add(x, y):return xydef sub(x, y):return x - ydef mult(x, y):return x * ydef calculator(opcode):if opcode == 1:return addelif opcode == 2:return subelse:return multmy_calc = calculator(2) #my calc is a subtractormy_calc(5, 4) #returns 5 - 4 = 1my_calc = calculator(9) #my calc is now a multipliermy_calc(5, 4) #returns 5 x 4 = 20.

嵌套函数

函数还可以在其他函数内部,这就是「内部函数」。内部函数在创建辅助函数时非常有用,辅助函数即作为子模块来支持主函数的小型可重用函数。

在问题需要特定函数定义(参数类型或顺序)时,我们可以使用辅助函数。这种不遵循传统做法的操作使得解决问题变得更加简单,示例参见:http://www-inst.eecs.berkeley.edu/~cs61a/sp12/lectures/lect4-2x3.pdf。

假设你想定义一个斐波那契函数 fib(n),该函数只有一个参数 n,我们必须返回第 n 个斐波那契数。

定义此类函数的一种可行方式是:使用辅助函数来追踪斐波那契数列的前两个项(因为斐波那契数是前两个数之和)。

def fib(n):def fib_helper(fk1, fk, k):if n == k:return fkelse:return fib_helper(fk, fk1 fk, k 1)if n <= 1:return nelse:return fib_helper(0, 1, 1)

将该计算从函数主体移到函数参数,这具备非常强大的力量。因为它减少了递归方法中可能出现的冗余计算。

单表达式函数(lambda 表达式)

如果我们想在未给函数命名之前写一个函数要怎么做?如果我们想写一个简短的单行函数(如上述示例中的函数 foo 或 mult)要怎么做?

我们可以在 Python 中使用 lambda 关键字来定义此类函数。示例如下:

mult = lambda x, y: x * ymult(1, 2) #returns 2

该 mult 函数的行为与使用传统 def 关键字定义函数的行为相同。

注意:lambda 函数必须为单行,且不能包含程序员写的返回语句。

事实上,它们通常具备隐式的返回语句(在上面的示例中,函数想表达 return x * y,不过我们省略了 lambda 函数中的显式返回语句)。

lambda 函数更加强大和精准,因为我们还可以构建匿名函数(即没有名称的函数):

(lambda x, y: x * y)(9, 10) #returns 90

当我们只需要一次性使用某函数时,这种方法非常方便。例如,当我们想填充字典时:

import collectionspre_fill = collections.defaultdict(lambda: (0, 0))#all dictionary keys and values are set to 0

接下来我们来看 Map、Filter 和 Reduce,以更多地了解 lambda。

Map、Filter 和 Reduce

Map

map 函数基于指定过程(函数)将输入集转换为另一个集合。这类似于上文提到的 iterate_custom 函数。例如:

def multiply_by_four(x):return x * 4scores = [3, 6, 8, 3, 5, 7]modified_scores = list(map(multiply_by_four, scores))#modified scores is now [12, 24, 32, 12, 20, 28]

在 Python 3 中,map 函数返回的 map 对象可被类型转换为 list,以方便使用。现在,我们无需显式地定义 multiply_by_four 函数,而是定义 lambda 表达式:

modified_scores = list(map(lambda x: 4 * x, scores))

当我们想对集合内的所有值执行某项操作时,map 函数很有用。

Filter

就像名称所显示的那样,filter 函数可以帮助筛除不想要的项。例如,我们想要去除 scores 中的奇数,那么我们可以使用 filter:

even_scores = list(filter(lambda x: True if (x % 2 == 0) else False, scores))#even_scores = [6, 8]

由于提供给 filter 的函数是逐个决定是否接受每一个项的,因此该函数必须返回 bool 值,且该函数必须是一元函数(即只使用一个输入参数)。

Reduce

reduce 函数用于「总结」或「概述」数据集。例如,如果我们想要计算所有分数的总和,就可以使用 reduce:

sum_scores = reduce((lambda x, y: xy), scores)#sum_scores = 32

这要比写循环语句简单多了。注意:提供给 reduce 的函数需要两个参数:一个表示正在接受检查的项,另一个表示所用运算的累积结果。

  • Best Practices for Using Functional Programming in Python:https://kite.com/blog/python/functional-programming/

  • Functional Programming Tutorials and Notes:https://www.hackerearth.com/zh/practice/python/functional-programming/functional-programming-1/tutorial/

原文链接:https://medium.com/better-programming/introduction-to-functional-programming-in-python-3d26cd9cbfd7

    推荐阅读
  • 失业没有交社保怎么办(失业没有交社保解决方法分享)

    失业没有交社保怎么办?下面希望有你要的答案,我们一起来看看吧!失业没有交社保怎么办首先,失业之后,社保其实我们并不需要担心,我们只需要找到下一份工作,然后就可以续交社保了,这样也就可以继续使用社保里面的钱了,这并没有什么问题。最后,办理完成后,我们需要定期将每个月缴纳的费用提前存入银行卡里面,之后就会定期在我们的银行卡里面扣款了,这样我们也就个人缴纳社保了。

  • 外国大学的课程要求(这项海外大学的必备技能)

    在多数欧美大学中,presentation甚至是考试成绩能否拿到A的关键。例如英国前首相丘吉尔的“铁幕演说”,当然还有众所周知的美国大选,每一位参与大选的候选人都是一位出色的演说家。最终很有可能获得“A”的考试成绩。03Presentation的准备精心制作PPT有人说presentation是一场演出。经常锻炼presentation的学生面试过程中,即使有一些突发情况,也可以从容面对。如今世界顶尖名校的申请越来越激烈,在同等的硬性要求下,presentation可以让学生在众多竞争者中脱颖而出。

  • 新车到底用不用拉高速(新车拉高速的合适时间和注意事项)

    将每一个挡位的转速拉到5000转以上,这样才能让活塞和齿轮尝试高速的工作状态,达到拉高速的意义。拉高速,一般是指新车过了磨合期后要上高速去拉一下车。通过拉高速可以让车在今后的驾驶中能有着良好的动力,以及换挡时的顺畅。车辆拉高速不等于开高速。车辆拉高速主要是为了让发动机在不同档位时的转速达到高值,跟车辆行驶的绝对速度是两个不同的概念。拉高速完成后,切忌超级降挡,应该逐级降挡,回到正常档位后匀速行驶。

  • 无印良品算是国际品牌吗(为什么无印良品)

    同时,无印良品严格要求其产品的整个生产流程,仅保留必要的生产工序,最大限度利用原材料,降低生产成本,研发真正必需的产品。在产品的造型设计方面,无印良品也严格遵守设计原则,造型简洁,多用线条简单的几何图形,避免不必要的凹凸,不设花纹、格纹,充分考虑产品与环境的和谐性。

  • 熟羊杂汤最简单的做法(熟羊杂汤最简单的做法是什么)

    把所有食材清洗干净先处理羊肺,在羊肺气管灌入清水,反复多次排出肺内的脏东西,直到羊肺变白色,在肺上划一刀将液水挤出,用清水冲洗干净将羊肠、羊肚加盐和面粉揉搓,去除黏液及肚里的油和杂质,今天小编就来说说关于熟羊杂汤最简单的做法?熟羊杂汤最简单的做法把所有食材清洗干净。煮羊杂汤不要加花椒大料易窜味。羊杂汤煮好后,放在汤中浸泡一晚上,次日,捞出葱姜不要。这样半成品的羊杂汤就做好了。

  • 萝卜丸子这样做外酥里嫩特别好(萝卜丸子最正宗的做法)

    萝卜丸子这样做外酥里嫩特别好萝卜丸子最正宗的做法,不加一滴水,外酥里软不油腻,省时又省力。萝卜丸子是我们山东这边一道特色的名吃,主要是由萝卜丝和面粉制作而成的素丸子。其实进入凉爽的秋天之后,只要一有时间我家就会做一次萝卜丸子吃。胡萝卜一根将其切成细丝。最后在擦丝的时候,一定要注意安全,防止擦伤手。将其大火汆烫2分钟。

  • 撞憬什么意思(词语撞憬什么意思)

    下面希望有你要的答案,我们一起来看看吧!撞憬什么意思原词为“憧憬”,汉语词汇,拼音chōngjǐng,意思是对某种事物的期待与向往。出自茅盾《创造》二:“君实在二十岁时,满脑子装着未来生活的憧憬。”

  • 北方北风那个吹(北风那个吹一)

    刘明约王恨颖出来是有目的的,怎能善罢干休。这一分手就是二十年,再见面时,刘明已经大学毕业,参加工作都十年了。女领导姓王,叫恨颖,是行政部总监,也就是刘明的顶头上司。刘明开车,王总坐在副驾。一路无话,来到临市后,刘明停好车,习惯性地用左手去拉车门,准备为王总开车门。既然领导不高兴,刘明也不想自讨没趣,在房间打开随身的笔记本电脑,查看了下这次会议的议程安排。

  • 拳皇97各大高手代表人物(拳皇97十大高手终极排名)

    在去年有一段时间赞助赛中多次胜了吴志辉,被网友调侃为格斗区只有一个辉辉那就是我“西安陈珲”。小虎个人理解包王对拳皇97各人物属性的理解特别透彻,尤其是对全人物拳脚判定掌控更是炉火纯青。前一阵与秦虹抢29大战多次战胜秦虹。现在跳槽某鱼格斗区被评为某鱼格斗区第一玛丽,混得也是风生水起!近期实力明显进步飞速,两天之内二连胜河池。拳皇97实力S级,手法好,意识强,反应敏捷。

  • 森的意思及寓意(森的意思及寓意是什么)

    以下内容大家不妨参考一二希望能帮到您!森的意思及寓意寓意茂盛、众多。根据姓名学字典,森字,本义是指树木丛生的现象,后也形容其他事物的众多、茂盛或森严,幽暗。作人名时,主要是取其茂盛、众多之义。森字读音是sēn,起名笔画数是12划,五行属木。卜易居根据森字的属性和寓意判断,森字做男孩或者女孩名字都适合。