Python基础:函数式编程-高阶函数

高阶函数

高阶函数

函数名也是变量

由于abs函数实际上是定义在import builtins模块中的,所以要让修改abs变量的指向在其它模块也生效,要用import builtins; builtins.abs = 10

高级函数

# -*- coding: utf-8 -*-
def add(x, y, f):
    return f(x) + f(y)

print(add(-5,6,abs))

map/reduce

map

map()接收两个参数,一个是函数,一个是Iteratormap()将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。

def f(x):
    return x * x

r = map(f,[1,2,3,4,5,6,7,8,9])
print(list(r))

把一个list所有数字转化为字符串:print(list(map(str,1,2,3,4)))

reduce

reduce(f,[x1,x2,x3,x4]) = f(f(f(f(x1,x2),x2),x3),x4)
比如序列求和:

from functools import reduce
def add(x,y)
    return x + y

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

把序列变成整数,结果将是1234:

from functools import reduce
def fn(x,y):
    return x * 10 + y

print(reduce(fn,[1,2,3,4]))

str转换为int的函数:

from functools import reduce
def fn(x,y):
    return x * 10 + y

def char2num(s):
    digits = {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}
    return digits[s]

reduce(fn,map(char2num,'1359'))

整理成一个函数:

from functools import reduce

DIGITS = {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}

def str2int(s):
    def fn(x,y):
        return x * 10 + y
    def char2num(s):
        return DIGITS[s]
    return reduce(fn,map(char2num,s))

print(str2int('12345'))

使用lambda函数进一步简化:

from functools import reduce

DIGITS = {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}

def char2num(s):
    return DIGITS[s]

def str2int(s):
    return reduce(lambda x, y: x * 10 + y, map(char2num, s)) # 注意计算顺序

print(str2int('12345'))

quiz

  1. 利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']
# -*- coding: utf-8 -*-

L1 = ['adam','LISA','barT']

def normalize(name):
    return name[:1].upper() + name[1:].lower()

L2 = list(map(normalize,L1))

print(L2)
  1. Python提供的sum()函数可以接受一个list并求和,请编写一个prod()函数,可以接受一个list并利用reduce()求积:
# -*- coding: utf-8 -*-
from functools import reduce

def prod(li):
    return reduce(lambda x,y:x * y,li)

print(prod([1,2,3,4])
  1. 利用mapreduce编写一个str2float函数,把字符串'123.456'转换成浮点数123.456
# -*- coding: utf-8 -*-
from functools import reduce

DIGITS = {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}

def str2num(li):
    return DIGITS[li]

def str2float(li):
    n = 0

    while li[n] != '.':
        n += 1
    dec = len(li) - n -1

    return float(reduce(lambda x,y:x * 10 + y, map(str2num,li[:-dec-1]+li[-dec:]))/(10 ** dec))

l3 = '123.456'
print(str2float(l3))

filter

filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

把一个序列中的空格字符串删掉

# and用法与:从左到右扫描,返回第一个为假的表达式值,无假值则返回最后一个表达式值。
# or用法或:从左到右扫描,返回第一个为真的表达式值,无真值则返回最后一个表达式值。
def not_empty(s):
    return s and s.strip()

print(list(filter(not_empty, ['A', '', 'B', None, 'C', '  '])))
# 结果: ['A', 'B', 'C']

用filter求素数

矮氏筛法求素数:

# 产生1000内的素数
# 构造一个从3开始的奇数序列生成器
def _odd_iter():
    n = 1
    while True:
        n += 2
        yield n

# 定义一个筛选函数
def _not_divisible(n):
    return lambda x: x % n > 0  # 匿名函数:定义x,如果x不能被n整除,则返回True

# 定义不断返回下一个素数的生成器
def primes():
    yield 2
    it = _odd_iter()  # 初始序列
    while True:
        n = next(it)  # it本身也是一个generator
        yield n
        it = filter(_not_divisible(n),it)  #通过函数将n整除的去掉

for n in primes():
    if n < 1000:  # 通过输出值与1000判断
        print(n)
    else:
        break

产生10000以内的回文数

from functools import reduce

def is_palindrome(num):
    return str(num) == reduce(lambda x,y:y + x,list(str(num)))  # str直接转list

def geplinum(max):
    return list(filter(is_palindrome, list(range(max+1))))  #在python中,filter, map, zip等返回可迭代的对象,返回的仅仅是一个元素,并不是一个列表,所以结果前需要使用list

print(geplinum(10000))

取str的倒序字符串也可以更简单地用str(n)[::-1]来表示。

sorted

sorted()函数可以对list进行排序,也是一个高阶函数,可以接受一个key函数来实现自定义排序,返回原值。

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

sorted对字符串比较时,是通过首字符的ASCII码进行比较,也可以加入反向排序:

>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key = str.lower, reverse = True)
['Zoo', 'Credit', 'bob', 'about']

用sorted对一组tuple按照名字和成绩排序:

# -*- coding: utf-8 -*-

L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]

def by_name(t):
    return t[0].lower()

def by_score(t):
    return -t[1]

L2 = sorted(L, key = by_name)
L3 = sorted(L, key = by_score)

print(L2)
print(L3)

你可能感兴趣的:(Python基础:函数式编程-高阶函数)