Python3函数式编程
来源:互联网 发布:淘宝运费模块名称 编辑:程序博客网 时间:2024/05/16 08:10
python3手册的目录
Python与函数式编程
Python的函数式不是特别有名, 但是我们还是可以做一些函数式编程的.
Python目前没有内置的不可变集合类库像Clojure设计的那样优秀. Clojure的不可变的集合不仅在修改的时候对内存的利用率很高, 并且很适合多线程直接传递数据. 避免加锁.
下面介绍的函数式编程使用的是Python3内建的集合类, 在多线程之间传递时, 我们要做好加锁工作. 或者做深度拷贝. 或者我们将对共享资源的访问给一个线程来操作, 其他线程通过queue
模块来给操作资源的那个线程发送命令. queue
的使用示例: Python3多线程编程
下面的方式不叫函数式编程
下面的方式中, 函数increment
使用了外部的变量a
, 因此有副作用
a = 0def increment(): global a a += 1
下面的方式是函数式编程
def increment(a): return a + 1
什么是函数式编程
函数式编程是一种编程模式, 它避免使用可变数据类型, 避免状态的改变. 流行的函数式语言有: Lisp, Haskell, Clojure.
函数式语言是描述型语言的子集. 描述型语言区别于命令型语言(c/c++,go,java)
函数式语言的特点
- 避免用全局状态的来解决问题
- 使用不可变数据类型(最好设计成内存使用率高的方式)
- 在语言中, 函数是一等公民(像java就不是)
- 使用高阶函数
- 使用递归函数
前两条主要是用来消除副作用. 如果状态的变更不依赖于输入函数的输入, 那么查找bug会是很麻烦是事情.
状态的表示和转移
在函数式编程中, 函数将输入转变成输出, 不产生和维护中间状态.
我们来看看下面的例子:
def square(x): return x*xinput = [1, 2, 3, 4]output = []for v in input: output.append(square(v))
def square(x): return x*xinput = [1, 2, 3, 4]output = map(square, input)
以上两段代码完成的任务是一样的. 但是我们可以看到, 第二种没有中间状态. 第一种在执行的时候, output
变量一直在改变, 并且是可以被其他线程访问到的. 但是第二种不改变input
也不产生中间状态, 只有计算完后, 才输出output
变量.
一等公民的函数, 和高阶函数
在Python我们可以直接定义一个函数, 然后使用它, 不像Java, 必须有一个对象或者类的前提下才能使用函数.
def greet(name): print("Hello %s!" % name)say_hello = greetsay_hello('World')# Hello World!
高阶函数, 就是把函数作为参数的函数, 或者返回一个函数的函数.
比如Python中的内建函数map()
reduce() 以及 filter()
reduce
函数将一个序列的数据, 归结为一个输出.
from functools import reducesum = reduce(lambda a, x: a + x, [0, 1, 2, 3, 4])
filter
函数将一个序列中的每个元素进行筛选, 并且返回一个新的序列
def is_odd(n): return n%2 == 1print(is_odd(2))# Falseprint(is_odd(3))# Truevalues = [1, 2, 3, 4, 5, 6]result = filter(is_odd, values)print(list(result))# [1, 3, 5]
生成器以及懒赋值
在Python中, 生成器Generator Functions和生成器表达式Generator Expressions他们的行为都跟迭代器一样. 好处就是不必预先将整个数据序列计算出来并且放入内存. 只是需要再使用的时候才去计算, 用多少计算多少call-by-need strategy
. 下面的图为 generator iterator iterable container 之间的关系.
代码示例
下面的例子默认:
from funcs import seq
使用了链式调用, 类似 Kotlin 的风格
例子1:
对一个序列进行循环迭代, 然后只取前10个元素, 最后将取到的10个元素保存到list中. 这里不到最后的list()调用, 是不会将整个结果生成到内存中的. 这样对于需要大量的数据进行迭代的应用来说, 效率很高, 对内存很友好.a =seq([1, 22, 3, 45]).cycle().head(10).list()print(a)输出: [1, 22, 3, 45, 1, 22, 3, 45, 1, 22]
例子2:
将多个序列合并a = seq([1, 22, 3, 45]).chain([1, 2, 4, 5, 2], [5, 65, 6, 90])print(list(a))输出: [1, 22, 3, 45, 1, 2, 4, 5, 2, 5, 65, 6, 90]
例子3:
对序列进行求平方, 再过滤出大于5的列表, 最后对列表进行求和, 求和的初始值为0. 也就是说, sum的初始值为0, x从filter()产出的列表的第一个元素开始遍历.a = seq([1, 2, 3, 4, 5]).map(lambda x: x ** 2).filter(lambda x: x > 5).reduce(lambda sum, x: sum + x, 0)print(a)输出: 50
funcs.py 模块
import collectionsfrom functools import reducefrom array import arrayimport itertoolsclass seq: def last_index(self): t = list, array, str, tuple, bytes if isinstance(self.data, t): return len(self.data) - 1 else: raise TypeError(f"{type(self.data)} is not instance of {t}") def size(self): t = collections.Sized, if isinstance(self.data, t): return len(self.data) raise TypeError(f"{type(self.data)} is not instance of {t}") def __init__(self, _s): t = collections.Iterable, if isinstance(_s, t): self.data = _s else: raise TypeError(f"{type(_s)} is not instance of {t}") def __iter__(self): return iter(self.data) def map(self, f): return seq(map(f, self.data)) def filter(self, f): return seq(filter(f, self.data)) def reduce(self, f, init=None): return reduce(f, self.data, init) def zip(self, *iter): return seq(zip(self.data, *iter)) def cycle(self): return seq(itertools.cycle(self.data)) def chain(self, *iter): return seq(itertools.chain(self.data, *iter)) def list(self): return list(self) def head(self, n=10): def gen(): nonlocal n for d in self: if n <= 0: break n -= 1 yield d return seq(gen())
参考:
Functional Programming in Python
A practical introduction to functional programming
- Python3函数式编程
- Python3函数式编程
- Python3 函数式编程
- Python3.X之函数式编程笔记
- Python3.5——函数与函数式编程
- Python3.5——函数式编程之参数详解
- 看代码学编程之python3函数
- Python3学习笔记(5)——函数和函数式编程
- 我的Python3学习笔记(2):python函数式编程
- 廖雪峰《python3 基础教程》读书笔记——第六章函数式编程
- python3 函数
- Python3 函数
- Python3函数
- python3 函数
- Python3函数
- Python3 函数
- python3函数
- Python3 函数
- Java使用Jetty实现嵌入式的Servlet容器
- vue系列
- [LWIP学习]--udp_input函数分析
- 利用Caffe+Python实现Kaggle上Digit Recognition练手项目
- Git可视化极简易教程 — Git GUI使用方法
- Python3函数式编程
- 实例详解机器学习如何解决问题
- BPMN 2.0规范详解
- 使用spring-loaded热部署
- python django 使用记录
- 一个了解和熟知中国物联网的网站分享
- keras系列︱图像多分类训练与利用bottleneck features进行微调(三)
- C++中的explicit关键字 抑制隐式转换构造
- 在mybatis中使用多语句执行需要注意的地方