【问题标题】:Python: List Comprehension and Functional ProgrammingPython:列表理解和函数式编程
【发布时间】:2012-06-13 04:14:01
【问题描述】:

在我的Python学习书中,当我读到List Comprehension时,作者有一个小注解释:

Python 的列表推导式是该语言支持的一个示例 函数式编程概念。

我在维基百科上阅读了有关函数式编程的信息。但我很难想象,因为我看不到 List Comprehension 与解释 wiki 页面中的这个概念之间的任何联系。

请给我一个清楚的解释(如果可以的话,给我更多关于 Java 或 C# 函数式编程的例子:D)

【问题讨论】:

  • java 和 c# 不是函数式语言
  • @Denis 不,你错了。许多例子为你证明。 LINQ 基于函数编程。并且有一本书:Functional programming in .NET。在 Java 中,我不知道。
  • 如果 C# 是 microsoft 为 F# 制作的函数式语言,Lol?您将范式与语法糖混淆了。
  • 在 OOP 范式中,您通过继承、多态性和封装来描述现实世界的对象,例如 car->truck->volvo truck,但在功能范式中,您在 lambda、monad 等中描述同一个世界作为一组有限的自动化。抱歉,我的英语很差,不适合讨论这种性质
  • @alan 我的问题是:我想解释一下原因。而且我认为,如果我有更多示例,我会更清楚地理解:)

标签: python functional-programming list-comprehension


【解决方案1】:

如果你的问题是“给我一些例子来说明 FP 在 python 中的工作原理”,那么:

什么是纯函数式编程(在 Python 中)?

它是一种编程范式,它避免了状态和可变数据,而是依赖于函数返回值。这意味着用 python 编写的纯函数式程序不会有变量、状态等。

不是那么纯粹的 FP

您可以将 FP 和命令式范式结合起来,并且效果很好(请参阅here)。链接的要点是我为几个月前学习的 Python 课程制作的数学测验程序。随意对代码做任何你想做的事情。

Java/C# 中的 FP

我个人没有使用 C# 的经验,因此其他人需要发布 C# 示例,但是您可以在 Java 中使用 FP,但不能使用纯 FP。示例:

int fib (int x) { 
    if (x < 2) return x;
    return fib (x-1) + fib(x-2);
}

上面的方法完全是FP,但是在使用Java时不能在纯FP上下文中使用。这需要放在 Java 中的 C 类中,并且只能在您实例化该类型的对象之后调用。最后一部分取消了 Java 类 C 的 FP 资格,但方法仍然是。

编辑:实际上,您可以在 Java 中使用静态方法,无需任何实例化即可使用。因此,如果您将签名更改为 static int fib (int x) ,那么如果以 FP 方式调用,则该方法及其方法调用可能仍然是 FP。


回复:你的评论

递归可能是 FP,但不一定是(见下文):

def f(first, rest):
    print first
    first = rest[0]; rest = rest[1:]
    f(first, rest)

你也可以在没有递归的情况下使用 FP:

 def sum (a,b):
     return a+b

 def square(c):
     return c*c

 def square_of_sum (x,y):
     return square(sum(x,y))

【讨论】:

  • 哦。你的代码是递归的,我们称之为 FP ?如果这是真的,这个例子并不能说服我太多,因为它太慢了,其他方法无法解决。
【解决方案2】:

我相信 Python 的列表推导直接取自 Haskell(一种非常“纯”的函数式语言)。

哈斯克尔:

[ x | x <- [1..10] ]

Python:

[ x for x in range(1,11) ]

正如人们所提到的,Python 确实允许函数概念,例如 map()reduce()lambda

虽然这些都是函数式的想法,但它们很少能以纯粹的函数式方式使用,因为 Python 不是递归友好的。

如果您想了解“功能性”语言,请查看“Haskell”、“Scala”、“Clojure”、“Erlang”、“F#”……它们或多或少都具有功能性(尽管有些人可能会建议事实并非如此)

如果你真的想了解什么是函数式编程,请看这里。 learn you a haskell for great good 很容易阅读,有漂亮的图片,会让你大开眼界。

编辑-

Haskell 阶乘函数示例(都做同样的事情):

fact1 0 = 1
fact1 n = n * fact1 (n - 1)


fact2 n | n == 0 = 1
        | otherwise = n * fact2 (n - 1)


fact3 n = case n of
            0 -> 1
            _ -> n * fact3 (n - 1)

ps,看看这个question 以及它是否相关。

【讨论】:

  • hmmm 我不会说 Python 的列表解析来自 Haskell,但很可能来自 set theory ... Haskell 和 Python 只是实现这种语法糖的 long list of languages 的一部分。
【解决方案3】:

我觉得很简单 术语 Map 和 Reduce 来自 Lisp 和函数式编程。

而python有

过滤、映射和减少

参考:http://www.joelonsoftware.com/items/2006/08/01.html

 http://docs.python.org/tutorial/datastructures.html

【讨论】:

    【解决方案4】:

    Python 的map(), reduce() and filter() 获取一个序列,将您选择的另一个函数应用于它,然后返回一个不同的序列给您,保持原始序列不变。

    您可以说这是功能性的,因为它不会触及原始序列,不会触及其内部状态并且不会产生副作用。 (虽然你自己提供给它的功能可以做上面的一些,比如产生副作用)

    Functional Programming 是一种不同的编程和构建应用程序的方式,以减少由副作用(直接更改另一个静态位置或进程中的某些值)引起的错误,并减少或消除同步访问共享数据的需要。有些语言会强迫你这样做,比如erlang,而另一些语言则让你自己选择最适合你的路径(过程或功能),优先考虑编程范围的功能方面,比如scala

    【讨论】:

    • 副作用。这个词我真的不是很懂。你能给我一个例子吗? (这意味着我不知道哪个问题会在 OOP 而不是函数式编程中产生副作用)
    • 副作用基本上是任何影响“外部世界”(您的功能范围之外的外部含义)的东西,即使是简单的文本打印也是一种副作用。
    • 是的,这才是重点。假设 *a(可以是任何东西)被并发进程或线程更改,而另一个进程/线程正在使用它。因此,您的例行程序的结果可能与您进入例程时的结果不同。在这种情况下防止它的唯一方法是通过互斥锁锁定您的数据访问。纯函数式编程的实际优势只有在您的程序并行执行其例程时才会真正体现出来,因为不变性和消息传递保证您将只处理您提供的数据。
    • 它基本上确保 double(a) [a=4] 返回 8 而不是 16,因为另一个进程在返回 a * 2 之前更改了 (a) 所代表的任何内容。 (这是可能的,因为 cpu 可以在进入例程之后但在进行计算之前抢占您的线程,如果您没有明确禁止它这样做)它保证了您的例程功能的不变性。
    • @hqt 一个简单的副作用示例是,如果您的函数修改了全局变量
    【解决方案5】:

    我相信其他人会比我更好地解释它,但函数式编程主要与您如何看待程序流程以及您是否可以将函数作为对象传递以进行计算有关在。例如,在 javascript 中,当你提供一个在偶数触发时要执行的函数时,这是在传递一个函数,从这个意义上说,它几乎就像函数式编程。

    这就是列表理解类似于函数式编程的意义,因为您提供的是有关如何计算每个元素的说明,而不是更程序化的方法,即循环并自己进行计算,而不是将其作为功能。 Python 并不是我真正认为的真正的函数式编程语言,如 LISP、ML 或 Haskell(是 erlang 吗?不记得了),但它可以做类似的事情(查看 python 中的 lambda 表达式)。

    Java 和 C/C++ 也不是真正的函数式,但您可以使用函数指针作为参数来模拟它。对C#不太熟悉...

    事件驱动语言倾向于更多地利用函数传递的这种思想,因为它们需要某种方式来传递未知代码,以便在以后执行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-16
      • 2021-09-10
      • 2012-11-12
      • 2020-08-03
      • 2011-08-05
      • 2015-02-01
      相关资源
      最近更新 更多