廖雪峰python教程(3)——函数式编程

1. 高阶函数

1.1 map/reduce

【1】一文搞懂python的map、reduce函数
【2】廖雪峰python教程——函数式编程

(1)map 函数

map(function_to_apply, list_of_inputs)

  • function_to_apply 代表函数
  • list_of_inputs 代表输入序列
  • 返回迭代器
# 如要实现列表中每个元素的平方,并返回新列表
items = [1, 2, 3, 4, 5] 
squared = []
for i in items:
    squared.append(i**2)

# 用map实现
items = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, items))

(2)reduce 函数
在这里插入图片描述

reduce(function, iterable[, initializer])

  • function 表示函数
  • iterable 表示序列
  • initializer 初始值(可选)
def add(x, y ):
    return x + y

result = reduce(add, [1,2,3,4,5])
print(result)

1.2 filter

用于过滤序列 filter(function, iterable)

  • function 判断函数
  • iterable 可迭代的对象
  • 返回的是一个 iterator ,是一个惰性序列。要强迫 filter() 完成计算结果,需要用list()函数获得所有结果并返回 list

关于廖雪峰老师filter教程中求素数详细理解

# 埃氏筛法
# 定义筛选函数,判断输入是否能被n整除,如果被整除那么这个输入就不是素数
def _not_divisible(n):
    return lambda x: x % n > 0

# 定义一个生成器,不断返回下一下素数
def primes():
    yield 2 # 输出一个素数
    it = _odd_iter()
    while True:
        n = next(it)  # 返回序列的第一个数
        yield n
        it = filter(_not_divisible(n), it)

    # 打印1000以内的素数:


for n in primes():
    if n < 1000:
        print(n)
    else:
        break

1.3 sorted

students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
print(sorted(students, key=lambda s:s[2], reverse=True))

2. 返回函数

# 返回求和函数的函数
def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum
f = lazy_sum(1,2,3,4,5)
print(f)
print(f())

>>> <function lazy_sum.<locals>.sum at 0x000001C14A986620>
>>> 15
  • 在函数 lazy_sum 中又定义了函数 sum,并且,内部函数 sum 可以引用外部函数 lazy_sum 的参数和局部变量
  • 当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为闭包(Closure)
  • 调用 lazy_sum() 时,返回的并不是求和结果,而是求和函数。注意:调用 lazy_sum() 时,即便每次传入相同参数,但最终返回的函数还是不同的
  • 调用函数 f 时,才真正计算求和的结果

注意!返回闭包时要牢记:返回函数不要引用任何循环变量,或者后续会发生变化的变量。如下例:

def count():
    fs = []
    for i in range(1, 4):
        def f():
            return i*i
        fs.append(f)
    return fs

f1, f2, f3 = count()
print(f1()) 
>>> 9
print(f2()) 
>>> 9
print(f3()) 
>>> 9

答案全部都是9,而不是1 4 9 的原因是,返回的函数引用了变量 i ,但是并非立刻执行。等到3个函数都返回,它们引用的变量 i 均为3,因此最后是9

  • 原因在于,对于闭包来说,外函数会认为自己的临时变量可能在将来的内部函数中用到,所以每次外部函数结束时,它都在返回内部函数的同时,把自己(外部函数)的临时变量和内部函数绑定在一起,这就解释了全部都是9的原因。

  • 如果一定要引用循环变量,我们可以把每次循环的值,绑定给一个内层的函数。这样一来,无论该循环变量后续如何更改,已绑定到函数参数的值都不会变化了。

def count():
    def f(j):
        def g():
            return j*j
        return g
    fs = []
    for i in range(1, 4):
        fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
    return fs

f1, f2, f3 = count()

运行步骤:

  • 进入【count()】,因为还没调用 所以不进入内函数,进入【for循环】,i = 1,进入【f(1)】,进入【g()】,最后f() 返回一个绑定的参数 j=1和函数g(),函数添加到 fs=[ ] 中
  • 接着再进入【count()】,i = 2,进入【f(2)】,进入【g()】,最后f() 返回一个绑定的参数 j=2和函数g(),函数添加到 fs=[ ] 中
  • 同理得到循环 i = 3
  • 这样,最后 f1, f2, f3 = count(),就得到三个不同的值了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值