Python之高阶函数(一)

高阶函数引入

高阶函数英文叫Higher-order function。什么是高阶函数?我们以实际代码为例子,一步一步深入概念。 

大家都很熟悉abs()函数吧,这个函数的意思就是求某个数字的绝对值。

下面我们使用代码来看看这个函数的意思:

# 内置函数可以直接调用
print(abs(-10))

# 可以看出,内置函数可以直接赋值给变量
f = abs
print(f(10))

运行结果:

10
<built-in function abs>

Process finished with exit code 0

总结:我们很容易看出,内置函数可以被直接调用,也可以先赋值给变量,然后利用变量再行定义。

传入函数

既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

示例代码:

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


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

运行结果:

11

Process finished with exit code 0

map()和reduce()函数

map()

map(function, iterable, ...)

function -- 函数,有两个参数

iterable -- 一个或多个序列

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

示例代码:

def f(x):
    return x * x

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

运行结果:

<map object at 0x0000000000D6F518>
[1, 4, 9, 16, 25, 36, 49, 64, 81]

Process finished with exit code 0

分析:由于map()把结果作为新的Iterator返回,所以,当我试图打印返回值r时,得到的是一个迭代器的内存地址,只有将其list()后才能返回列表。

对比而言,使用for...in函数也可以做到这样的结果。

示例代码:

def f(x):
    return x * x


lst = []
for i in [1, 2, 3, 4, 5, 6, 7, 8, 9]:
    lst.append(f(i))
print(lst)

运行结果:

[1, 4, 9, 16, 25, 36, 49, 64, 81]

Process finished with exit code 0

分析:从上面的循环代码,我们能一眼看出来使用map()能够更加直观的了解返回的值为迭代器,代码简洁高效。事实上而言,map()作为高阶函数,它把整个运算规则抽象化了,我们不仅能用其解决平方这类的运算函数,还能计算任意比较复杂的函数。

示例代码:

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

运行结果:

['1', '2', '3', '4', '5', '6', '7', '8', '9']

Process finished with exit code 0

只需要一行代码,就可以把列表中的数字类型转化为字符串类型。

reduce()

reduce(function, iterable[, initializer])

function -- 函数,有两个参数

iterable -- 可迭代对象

initializer -- 可选,初始参数

reduce()把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算。

示例代码:

from functools import reduce


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


r = reduce(add, [1, 2, 3, 4, 5, 6, 7, 8, 9])
print(r)

运行结果:

45

Process finished with exit code 0

分析:使用reduce()必须要从functools中引入reduce()方法。r的计算步骤为:

先计算add(1 + 2)

然后计算add(add(1 + 2) + 3)

,,,

直到结果为:45

如果说这个例子没实在的意义,我们现在演示一些常用的操作:

示例代码:

from functools import reduce


def f(x, y):
    return x * 10 + y


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

运行结果:

123456789

Process finished with exit code 0

这是初一的一个算法,在这里就不多赘述。

示例代码:

def f(x, y):
    return x * 10 + y


def charNum(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]


r = reduce(f, map(charNum, "13579"))
print(r)

运行结果:

13579

Process finished with exit code 0
 

分析:这是一个将str类型数据转为int类型数据的方法,map(charNum,"13579")中,字符串遍历数字得到迭代列表[1,3,5,7,9],外层reduce()函数把该列表变为整数。

上面呢函数可以整理为:

示例代码:

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 strToInt(s):
    def f(x, y):
        return x * 10 + y

    def charToNum(s):
        return DIGITS[s]

    return reduce(f, map(charToNum, s))


r = strToInt('13579')
print(r)

运行结果:

13579

Process finished with exit code 0

也可使用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 charToNum(s):
    return DIGITS[s]


def strToInt(s):
    return reduce(lambda x, y: x * 10 + y, map(charToNum, s))


r = strToInt('13579')
print(r)

运行结果:

13579

Process finished with exit code 0

练习题

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

示例代码:

def normalize(name):
    return name.lower().capitalize()

r = map(normalize,["dfFddf","RRdfaFR","dfSSDFF"])
print(list(r))

运行结果:

['Dffddf', 'Rrdfafr', 'Dfssdff']

Process finished with exit code 0

 2. Python提供的sum()函数可以接受一个list并求和,请编写一个prod()函数,可以接受一个list并利用reduce()求积:

示例代码:

from functools import reduce


def prod(lst):
    def mul(x, y):
        return x * y

    return reduce(mul, lst)


# 这是测试
r = prod([1, 2, 3, 4, 5, 6, 7, 8, 9])
print(r)

运行结果:

362880

Process finished with exit code 0

可以使用lambda函数表示为:

示例代码:

from functools import reduce


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


# 这是测试
r = prod([1, 2, 3, 4, 5, 6, 7, 8, 9])
print(r)

运行结果:

362880

Process finished with exit code 0

3. 利用mapreduce编写一个str2float函数,把字符串'123.456'转换成浮点数123.456:

示例代码:

def str2float(s):
    nums = map(lambda ch: CHAR_TO_FLOAT[ch], s)
    point = 0

    def to_float(f, n):
        nonlocal point
        if n == -1:
            point = 1
            return f
        if point == 0:
            return f * 10 + n
        else:
            point = point * 10
            return f + n / point

    return reduce(to_float, nums, 0.0)


# 这是测试
print(str2float('0'))
print(str2float('123.456'))
print(str2float('123.45600'))
print(str2float('0.1234'))
print(str2float('.1234'))
print(str2float('120.0034'))

运行结果:

0.0
123.456
123.456
0.12340000000000001
0.12340000000000001
120.0034

Process finished with exit code 0

猜你喜欢

转载自blog.csdn.net/qq_33567641/article/details/81075851