# Making Your Python Codes More Functional

## 常用的函数

# 一般版本

# FP的版本

### iterators（迭代器）

In [4]: a  = [1,3,4]

In [5]: b = iter(a)

In [6]: next(b)
Out[6]: 1

In [7]: next(b)
Out[7]: 3

In [8]: next(b)
Out[8]: 4

In [9]: next(b)
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-9-641a931447e8> in <module>()
----> 1 next(b)

StopIteration:

1. 一次只用一个

2. 只有需要时才会产生数据。

### generator生成器

def lazy_integers(n = 0):
while True:
yield n
n += 1

xs = lazy_integers()

[next(xs) for _ in range(10)]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

[next(xs) for _ in range(10)]
# [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

#### 一个高阶的用法

squares = (x ** 2 for x in lazy_integers())
doubles = (x * x for x in lazy_integers())

next(squares) #0
next(squares) #1
next(squares) #4

#### 生成器模拟pipeline

with open("a.txt", "r") as f:
lines = (line for line in f)
prime_lines = filter(lambda line: "prime" in line.lower(), lines)

line_count = len(list(prime_lines))

## itertools模块

itertools模块提供了大量用于操作迭代器的函数。

count [start=0], [step=1] 输出无穷序列(start, start + step, start + 2 * step...)
islice seq, [start=0], stop, [step=1] 输出序列的切片
tee it, [n=2] 复制序列，输出为多个相同序列组成的元组
repeat elem, [n=forever] 重复序列n次，输出为一个repeat元素
cycle p 无限重复cycle里的元素
chain p, q, ... 迭代p里的元素，然后再迭代q的元素，...
accumulate p, [func=add] 返回(p[0], func(p[0], p[1]), func(func(p[0], p[1]), p[2])...)

### 自定义一些常用的迭代工具

def take(n, it):
"""
将前n个元素固定转为列表
"""
return [x for x in islice(it, n)]

def drop(n, it):
"""
剔除前n个元素
"""
return islice(it, n, None)

# 获取序列的头

# 获取除第一个元素外的尾
tail = partial(drop, 1)

def iterate(f, x):
yield x
yield from iterate(f, f(x))

def iterate(f, x):
while True:
yield x
x = f(x)

def iterate(f, x):
return accumulate(repeat(x), lambda fx, _:f(fx))

#### 使iterate

def lazy_integers():

take(10, lazy_integers())

## 一个例子：斐波那契数列

### 基本写法

def fib(n):
if n == 0: return 1
if n == 1: return 1
return fib(n - 1) + fib(n - 2)

[fib(i) for i in range(10)]

### 升级写法——mutable but functional

def fibs():
a, b = 0, 1
while True:
yield b
a, b = b, a + b

take(10, fibs())

def fibs():
yield 1
yield 1
yield from map(add, fibs(), tail(fibs()))

take(10, fibs())