龙空技术网

Python | 函数式编程(1)

VT聊球 93

前言:

现时大家对“pythonsquare”大约比较重视,大家都需要剖析一些“pythonsquare”的相关资讯。那么小编在网络上网罗了一些关于“pythonsquare””的相关文章,希望姐妹们能喜欢,你们一起来了解一下吧!

函数式编程范式

在命令式编程中,你通过给计算机一系列任务来解决问题。在执行任务时,它可以改变状态。例如,假设最初将A设置为5,随后你能更改A的值。变量的意义在于它的值是可变化的。

在函数式编程中,你不告诉计算机做什么,而是告诉它是什么。比如:一个数的最大公约数是多少,从1到n的乘积是多少,等等。

因此,变量的值不能改变。一旦设置了一个变量,它就永远保持这种状态(注意,在纯函数式编程语言中,它们不被称为变量)。所以,函数在函数式编程中没有副作用。所谓副作用是指函数改变了它外部的一些东西。让我们看一个典型的Python代码示例:

a = 3def some_func():    global a    a = 5some_func()print(a)

此代码的输出为5。在函数式编程中,改变变量的值是一个很大的禁忌,让函数影响作用域之外的东西也是一个很大的禁忌,函数唯一能做的就是计算并返回结果。

现在你可能会想:“没有变量,没有副作用,为何这么好呢?”问得好!你绝对是一个好奇宝宝。

用相同的参数调用两次函数,肯定会返回相同的结果。学过数学中的函数,都这么认为。这就是引用透明性。因为函数没有副作用,所以如果你正在构建一个用于计算的程序,你可以加快程序的速度。如果程序知道func(2) =3,我们可以将其存储在表格中。这可以防止程序在我们已经知道答案的情况下重复运行同一个函数。

通常,在函数式编程中,我们不使用循环,而是使用递归。递归是一个数学概念,意味着“自成一体”。递归函数反复将自身作为子函数来调用。下面是Python中递归函数的一个很好的例子:

def factorial_recursive(n):    # Base case: 1! = 1    if n == 1:        return 1    # Recursive case: n! = n * (n-1)!    else:        return n * factorial_recursive(n-1)

一些编程语言也很懒。这意味着他们直到最后一秒才开始计算或执行任何任务。如果你编写一些代码来执行2 + 2,那么只在你实际需要使用结果时,你的函数程序将才会计算这个值。我们很快就会探讨Python中的惰性。

Map

为了理解map,先了解可迭代对象。可迭代对象就是能够重复得到项的东西,比如列表或数组。Python有许多不同类型的可迭代对象。甚至可以通过“魔术方法”来创建你自己的可迭代对象,它就像调用API那样简单,让你创建一个可迭代对象:

class Counter:    def __init__(self, low, high):        # set class attributes inside the magic method __init__        # for "inistalise"        self.current = low        self.high = high    def __iter__(self):        # first magic method to make this object iterable        return self        def __next__(self):        # second magic method        if self.current > self.high:            raise StopIteration        else:            self.current += 1            return self.current - 1

第一个魔术方法:“__iter__” (在 iter两侧使用双下划线),返回实例对象自己。这种方法通常在循环开始时使用。

我们到终端界面并检验一下:

for c in Counter(3, 8):    print(c)

打印结果将会是:

345678

在Python中,迭代器是一个对象,它只有一个方法:__iter__。这意味着你可以访问对象中的位置,但不能遍历对象。有些对象将有方法__next__ ,而不是 __iter__ ,例如sets(本文稍后将讨论)。在本文中,我们假设我们所接触到的所有东西都是一个可迭代对象。

现在我们知道什么是可迭代对象了,让我们回到map函数。map函数允许我们把一个函数用于可迭代对象中的每一个项。通常我们希望把一个函数用于列表中的每一个项,但要知道:对于大多数可迭代对象来说,这是可能的。map接受2个输入:函数对象和可迭代对象。

map(function, iterable)

假设我们有这样的一个数字列表:

[1, 2, 3, 4, 5]

计算每个数字的平方,我们可以编写如下代码:

x = [1, 2, 3, 4, 5]def square(num):    return num*numprint(list(map(square, x)))

Python函数是编程中的函数是惰性加载的。如果不用list(),将返回迭代器对象,而不是列表本身。我们需要明确地告诉Python“把它变成一个列表”,以便使用它。

或许你对这种惰性计算感到唐突,如果你更多地用函数思维而不是命令思维,就会习惯的。

像上面那样,写一个square(num)这样的普通函数,是可以的,但不是最好的。我们必须定义一个完整的函数,才能在map中使用。更好的选择是直接使用lambda函数。

Lambda表达式

lambda表达式是一个单行函数。例如:求平方。

square = lambda x: x * x

现在我们来运行这个函数:

>>> square(3)9

我听到你说:“参数在哪里? 这是什么鬼东西? 它看起来一点也不像函数。”

嗯,这有点令人困惑,但可以解释。我们给变量square赋值。看这部分:

lambda x:

告诉Python这是一个lambda函数,输入的参数名为x。冒号后面的任何内容都是对输入的操作,它会自动返回结果。

要将求平方的程序简化为一行,我们可以执行以下操作:

x = [1, 2, 3, 4, 5]print(list(map(lambda num: num * num, x)))

所以在lambda表达式中,所有的参数都在左边,你想用它们所做的事情都在右边。有点乱,没人能否认这一点。事实上,编写只有其他函数式程序员才能阅读的代码是一种乐趣。另外,使用函数并将其转换为一行代码也是非常酷的。

标签: #pythonsquare #python函数编程200例