Python学习笔记二

今天看了函数式编程的内容,需要记录一下。

高阶函数

map/reduce

  • map()函数
    它接受两个参数,一个函数,一个Iterable,这个函数会作用于Iterable的每个元素,并把结果作为Iterator返回。
    比如:
>>> def f(x):
...     return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]

可见最后的结果是list中的每个元素都进行平方运算最后生成一个Iterator,然后用list方法进行输出。

  • reduce()函数
    它接受两个参数,一个函数,一个序列,用于把结果继续和序列的下个元素做累积计算。
    比如:
>>> from functools import reduce
>>> def fn(x, y):
...     return x * 10 + y
...
>>> reduce(fn, [1, 3, 5, 7, 9])
13579

list的前面两个元素做出的结果继续与后面的元素进行运算,以此类推。

filter

它也接受一个函数和一个序列作为参数,然后把传入的函数作用于序列中的每个元素,再根据返回的是True还是False决定保留或者删去元素。
比如:

>>> def is_odd(n):
...   return n % 2 == 0
>>> list(filter(is_odd,[2,3,4,5,7,9,10]))
[2, 4, 10]

这个函数就可以保留偶数。

sorted

一般的排序用法。

>>> sorted([36, 5, -12, 9, -21])
[-21, -12, 5, 9, 36]

或者

>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]

可以用key来指定排序的关键字。
当需要反向排序的时候可以这样:

sorted([-21, -12, 5, 9, 36],reverse=True)
[36, 9, 5, -12, -21]

加上reverse方法即可。

返回函数

  • 函数可以当做结果值返回。
    比如这个求和函数:
def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum
>>> f = lazy_sum(1, 3, 5, 7, 9)
>>> f
<function lazy_sum.<locals>.sum at 0x101c6ed90>

我们发现调用后返回的是一个函数而不是值,之后再次进行调用才可以。

>>> f()
25

当程序修改后才回返回计算的值:

def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum()
>>> f = lazy_sum(1, 3, 5, 7, 9)
>>> f
25
  • 闭包
    这样两个函数:
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,f2,f3)

输出1 4 9

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(),f2(),f3())

输出9 9 9
差别在哪里?
前者加入fs这个list的其实是经过计算后的值,也就是1、4、9。那么count()调用后就已经进行了运算,所以f1、f2、f3就分别对应的是list的三个值。
后者加入list的其实是三个函数,都是计算i*i的函数,也就是f1、f2、f3这三个元素。只有最后调用的时候才产生结果,那么调用的时候i已经是3了,所以结果相同了都是9。

匿名函数

匿名函数用法:

>>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
[1, 4, 9, 16, 25, 36, 49, 64, 81]

lambda x: x * x就是匿名函数。

装饰器

在代码运行期间动态增加功能的方式,称为“装饰器”。

  • 函数的名字
    函数对象有个name属性,可以拿到函数的名字,比如:
>>> int.__name__
'int'
  • 要增强某个函数的功能,希望在调用前后打印日志。
    比如:
def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

利用@语法:

@log
def now():
    print('2015-3-25')

调用now()函数:

>>> now()
call now():
2015-3-25

发现进行了日志输出。

偏函数

普通情况下,int会把字符串转换为整数,比如:

>>> int('12345')
12345

但是int()函数还提供额外的base参数,比如:

>>> int('12345', base=8)
5349
>>> int('12345', 16)
74565

利用偏函数:

>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64
>>> int2('1010101')
85

这样重新定义后的int2函数就可以把二进制字符串转化为十进制数了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容