高阶函数,柯里化,sort排序

高阶函数概念

first class object:
    函数在python中时一等公民.
    函数也是对象,可调用的对象.
    函数可以作为普通变量,参数,返回值等等.
高阶函数:
    数学概念: y=g(f(x)).
    在数学和计算机科学中,高阶函数应当是至少满足下面一个条件的函数:
    接受一个或多个函数作为参数.
    输出一个函数.

计数器:

def counter(base):
    def inc(step=1):
        base += step
        return base
    return inc

# print(counter(5)())
res = counter(5)
print(res())

分析:
函数counter是一个高阶函数.

该函数运行会报错,原因在于第3行, base = base + step, base被重新赋值.
改进: 使用nonlocal.

nonlocal会指引inc去上层非全局作用域的本地作用域中查找.

改进之后的counter函数,f1 = counter(5)和f2 = counter(5).

比较f1和f2,值相同,但内存地址不同.因为inc是counter内的函数,每次调用counter,inc都要在栈上重新生成对象,故内存地址不相等.

自定义sort函数

排序问题: 仿照内建函数sorted,实现一个sort函数(不使用内建函数),能够为列表元素排序.
思路:
    内建函数sorted会返回一个新的列表,可以设置升序或降序,设置的排序的函数,自定义的sort函数也要实现这个功能.
    新建一个列表,遍历原列表,和新列表的值依次比较决定如何插入到新列表中.

for函数的使用原则: 不建议修改源,除非明确知道需要修改,因为不一定只给一个人用,所以要选择使用sort和sorted.

实现示例:

def sort(iterable):
    ret = []
    for x in iterable:
        for i, y in enumerate(ret):
            if x < y:
                ret.insert(i, x)
                break
        else:
            ret.append(x)
    return ret

print(sort([1, 9, 5]))

sort函数实现,用一个参数控制顺序:

def sort(iterable, reverse=False):
    ret = []
    for x in iterable:
        for i, y in enumerate(ret):
            flag = x > y if reverse else x < y
            if flag:
                ret.insert(i, x)
                break
        else:
            ret.append(x)
    return ret

print(sort([1, 9, 5], reverse=True))

def sort(iterable, fn = lambda a, b : a < b):
    ret = []
    for x in iterable:
        for i, y in enumerate(ret):
            if fn(x, y):
                ret.insert(i, x)
                break
        else:
            ret.append(x)
    return ret

print(sort([1, 9, 5]))

内建函数-高阶函数

sorted(iterable[,key][,reverse]) 排序.
    返回一个新的列表,对一个可迭代对象的所有元素排序,排序规则为key定义的函数, reverse表示是否翻转.
    sorted(lst, key=lambda x:6-x) # 返回新列表.
    list.sort(key=lambda x:6-x) # 就地修改.

filter(function,iterable) -> filter object
    过滤可迭代对象的元素,返回一个迭代器.
    function一个具有一个参数的函数, 返回bool.
    例: 过滤出列表中能被3整除的数字.
       list(filter(lambda x: x % 3 == 0, [1,9,55,150,-3,78,28,123])

map(func, iterables) -> map object
    对多个可迭代对象的元素按照指定的函数进行映射,返回一个迭代器.
    ‡ list(map(lambda x:2
x+1, range(5)))
    ‡ dict(map(lambda x: (x%5,x) , range(500)))

注:
    sort和map不改变元素个数.
    filter可能会改变元素个数.

柯里化Currying

柯里化:
    指将原来接收两个参数的函数变成新的接收一个参数的函数的过程, 新的函数返回一个以原有第二个参数为参数的函数.
    z = f(x, y) 转换成 z = f(x)(y) 的形式.
举例: 将加法柯里化

def add(x, y):
    return x + y

print(add(5, 4))

def add(x):
    def _add(y):
        return x + y
    return _add

print(add(5)(4))

以上通过嵌套函数就可以把函数转换为柯里化函数.

posted @ 2017-11-12 21:45  yangbin  阅读(262)  评论(0编辑  收藏  举报