首页 » SEO优化 » php函数引用赋值技巧_写 Python 代码弗成不知的函数式编程技能

php函数引用赋值技巧_写 Python 代码弗成不知的函数式编程技能

访客 2024-12-18 0

扫一扫用手机浏览

文章目录 [+]

作者:Raivat Shah

参与:魔王、Jamin

php函数引用赋值技巧_写 Python 代码弗成不知的函数式编程技能

本文对 Python 中的函数式编程技能进行了大略的入门先容。

php函数引用赋值技巧_写 Python 代码弗成不知的函数式编程技能
(图片来自网络侵删)

比来,越来越多人利用函数式编程(functional programming)。
因此,很多传统的命令式措辞(如 Java 和 Python)开始支持函数式编程技能。
本文对 Python 中的函数式编程技能进行了大略的入门先容。
本文适宜对函数式编程有基本理解的读者。
如果你对函数式编程并不熟习,可以先阅读这篇文章:https://medium.com/@yannickdot/functional-programming-101-6bc132674ec5。

本文作者是新加坡国立大学打算机学院和「USP」博学操持学生 Raivat Shah,专注于编程与数据研究。

头等函数在 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 = greeting   def __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 x + ydef sub(x, y):    return x - ydef mult(x, y):    return x  ydef calculator(opcode):    if opcode == 1:       return add    elif opcode == 2:       return sub    else:       return mult my_calc = calculator(2) #my calc is a subtractormy_calc(5, 4) #returns 5 - 4 = 1 my_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 fk        else:           return fib_helper(fk, fk1+fk, k+1)    if n <= 1:       return n    else:       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 和 ReduceMapmap 函数基于指定过程(函数)将输入集转换为另一个凑集。
这类似于上文提到的 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 值,且该函数必须是一元函数(即只利用一个输入参数)。
Reducereduce 函数用于「总结」或「概述」数据集。
例如,如果我们想要打算所有分数的总和,就可以利用 reduce:

sum_scores = reduce((lambda x, y: x + y), 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

标签:

相关文章