高阶函数
接收/返回 函数 的 函数
reduce 归并 序列
# 利用map和reduce编写一个str2float函数,把字符串'123.456'转换成浮点数123.456
# -*- coding: utf-8 -*-
from functools import reduce
def str2float(s):
DIGITS = {
'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
def str2int(s1):
return reduce(lambda a,b:a*10+b, map(lambda ss:DIGITS[ss], s1) )
si = s.split(".")[0] # 整数位
sl = s.split(".")[1] # 小数位
ii = str2int(si)
ff = str2int(sl) / (10**len(sl)) # 小数位 按 整数位方式处理后 整体 处理
return ii+ff
# 法2
CHAR_TO_FLOAT = {
'0': 0,
'1': 1,
'2': 2,
'3': 3,
'4': 4,
'5': 5,
'6': 6,
'7': 7,
'8': 8,
'9': 9,
'.': -1
}
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)
筛选 序列 filter
# 回数是指从左向右读和从右向左读都是一样的数,例如12321,909。请利用filter()筛选出回数:
def is_palindrome(n):
def palindrome(n):
#'''
ll = []
ll.append(n%10)
s = n //10
while s > 9:
ll.append(s%10)
s //= 10
if n>9:
ll.append(s)
return ll == ll[::-1]
'''
sn = str(n)
if sn == sn[::-1]:
return n
'''
return palindrome(n)
#return list(filter(palindrome, range(1, n)))
# 测试:
output = filter(is_palindrome, range(1, 1000))
print('1~1000:', list(output))
if list(filter(is_palindrome, range(1, 200))) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191]:
print('测试成功!')
else:
print('测试失败!')
排序 序列
# -*- coding: utf-8 -*-
# 假设我们用一组tuple表示学生名字和成绩:
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
# 请用sorted()对上述列表分别按名字排序:
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_name(t):
return t[0].lower()
L2 = sorted(L, key=by_name)
print(L2)
# 再按成绩从高到低排序:
def by_score(t):
return t[1]
#by_score = itemgetter(1)
L2 = sorted(L, key=by_score, reverse=True)
print(L2)
返回函数的函数
# 函数作为返回值
# 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。
# 我们来实现一个可变参数的求和。通常情况下,求和的函数是这样定义的:
def calc_sum(*args):
ax = 0
for n in args:
ax = ax + n
return ax
# 但是,如果不需要立刻求和,而是在后面的代码中,根据需要再计算怎么办?可以不返回求和的结果,而是返回求和的函数:
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum
#当我们调用lazy_sum()时,返回的并不是求和结果,而是求和函数:
f = lazy_sum(1, 3, 5, 7, 9)
f
#<function lazy_sum.<locals>.sum at 0x101c6ed90>
#调用函数f时,才真正计算求和的结果:
f()
#25
#我们在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。
#请再注意一点,当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数:
>>> f1 = lazy_sum(1