在我的 Python 学习书中,当我读到 时List Comprehension
,作者有一个小注释解释:
Python 的列表理解是该语言支持函数式编程概念的一个示例。
我在维基百科上阅读了有关函数式编程的信息。但我很难想象,因为我List Comprehension
在解释的 wiki 页面中看不到与此概念之间的任何联系。
请给我一个清楚的解释(如果可以的话,给我更多关于 Java 或 C# 函数式编程的例子:D)
在我的 Python 学习书中,当我读到 时List Comprehension
,作者有一个小注释解释:
Python 的列表理解是该语言支持函数式编程概念的一个示例。
我在维基百科上阅读了有关函数式编程的信息。但我很难想象,因为我List Comprehension
在解释的 wiki 页面中看不到与此概念之间的任何联系。
请给我一个清楚的解释(如果可以的话,给我更多关于 Java 或 C# 函数式编程的例子:D)
如果您的问题是“给我一些例子来说明 FP 在 python 中的工作原理”,那么:
什么是纯函数式编程(在 Python 中)?
它是一种编程范式,它避免了状态和可变数据,而是依赖于函数返回值。这意味着用 python 编写的纯函数式程序不会有变量、状态等。
不那么纯粹的FP
您可以将 FP 和命令式范式结合起来,并取得良好的效果(参见此处)。链接的要点是我为几个月前学习的 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上下文中使用。这需要放在C
Java 中的类中,并且只能在您实例化该类型的对象后调用。最后一部分取消了 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))
Python 的map()、reduce() 和 filter()采用一个序列,将您选择的另一个函数应用于它,然后返回一个不同的序列给您,保持原始序列不变。
您可以说这是功能性的,因为它不会触及原始序列,不会触及其内部状态并且不会产生副作用。(尽管您自己提供给它的功能可以执行上述某些操作,例如产生副作用)
函数式编程是一种不同的编程和构建应用程序的方式,以减少由副作用(直接更改另一个静态位置或进程中的某些值)引起的错误,并减少或消除同步访问共享数据的需要。有些语言会强迫你这样做,比如erlang,而另一些语言则让你更多地选择当时最适合你的路径(过程或函数),优先考虑编程范围的函数方面,比如scala
我相信 Python 的列表推导直接取自 Haskell(一种非常“纯”的函数式语言)。
哈斯克尔:
[ x | x <- [1..10] ]
Python:
[ x for x in range(1,11) ]
正如人们所提到的,Python 确实允许函数概念,例如map()
、reduce()
和lambda
虽然这些都是函数式的想法,但它们很少能以纯粹的函数式方式使用,因为 Python 不是递归友好的。
如果您想了解“功能性”语言,请查看“Haskell”、“Scala”、“Clojure”、“Erlang”、“F#”……它们或多或少都具有功能性(尽管有些人可能认为这不是案子)
如果你真的想了解什么是函数式编程,请看这里。向你学习一个很好的haskell,它易于阅读,有漂亮的图片,会让你大开眼界。
编辑 -
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,看看这个问题以及它是否相关。
我确信其他人能够比我更好地解释它,但函数式编程主要与您如何看待程序流程以及您是否可以将函数作为对象传递以进行计算有关。例如,在 javascript 中,当您提供要在偶数触发时执行的函数时,这是在传递一个函数,从这个意义上说,它几乎就像函数式编程。
这就是列表理解类似于函数式编程的意义,因为您提供的是有关如何计算每个元素的说明,而不是更程序化的方法,即循环并自己进行计算,而不是将其作为函数传递。Python 并不是我真正认为的真正的函数式编程语言,如 LISP 或 ML 或 Haskell,(是 erlang 吗?不记得了)但它可以做类似的事情(查看 python 中的 lambda 表达式)。
Java 和 C/C++ 也不是真正的函数,但您可以使用函数指针作为参数来模拟它。对C#不太熟悉...
事件驱动语言倾向于更多地利用函数传递的这种思想,只是因为它们需要某种方式来传递未知代码以在以后执行。
我认为很简单 Map 和 Reduce 这两个术语来自 Lisp 和函数式编程。
和蟒蛇有
过滤、映射和减少
参考:http://www.joelonsoftware.com/items/2006/08/01.html
http://docs.python.org/tutorial/datastructures.html