日知录(三):python高阶函数

此后的python决定还是以代码为主来学习,有许多是在廖雪峰老师教程的讨论区看到的更好的方法,也贴在这里以拓展思路。

map()

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

eg1

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

# -*- coding: utf-8 -*-
def normalize(name):
    return name[0].upper()+name[1:].lower()     #方法一

    return name.lower().title()                 #方法二

    name = name.lower()                         #方法三
    return name[0].upper() + name[1:]

    return str.capitalize(name)                 #方法四


    s = name.title()                            #方法五
    return s


# 测试:
L1 = ['adam', 'LISA', 'barT']
L2 = list(map(normalize, L1))
print(L2)

注解一些方法帮助理解和运用:
1.str.upper()
描述:转换字符串中所有大写字符为小写
参数:无
返回值:返回将字符串中所有大写字符转换为小写后生成的字符串。

2.str.lower()
描述:转换字符串中所有小写字母为大写
参数:无
返回值:返回将字符串中所有小写字符转换为大写后生成的字符串。

3.str.capitalize()
描述:将字符串的第一个字母变成大写,其他字母变小写。
参数:无
返回值:返回一个首字母大写的字符串。

4.str.title()
描述:将字符串内的每个单词的首字母变成大写。
参数:无

5.切片:
用法 a[start::stop]
name[0]表示首字母,name[1:]表示首字母之后的所有字符串。

eg2

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

# -*- coding: utf-8 -*-
from functools import reduce
def prod(L):
    def multiplice(x, y):                   #方法一,容易理解
        return x * y
    return reduce(multiplice, L);


    return reduce(lambda x, y: x * y, L)    #方法二

# 测试:
print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9]))
if prod([3, 5, 7, 9]) == 945:
    print('测试成功!')
else:
    print('测试失败!')

注解一些方法帮助理解和运用:
1.lambda表达式
仅就本例对lambda表达式做出一些探讨:
举例说明

#该例用作讲一个list内的每个元素都平方
#法1
map(lambda x :x*x,[y for y in range (10)])
#法2
def sq(x):
	return x*x
map(sq,[y for y in range (10)])

法二多定义了一个函数(污染环境),特别是在这个函数只使用一次的情况下。
法一更易读,是一种匿名函数的用法。
上面的eg2中的两种方法也可以这么理解。

eg3

利用map和reduce编写一个str2float函数,把字符串’123.456’转换成浮点数123.456:

# -*- coding: utf-8 -*-
from functools import reduce

def str2float(s):
    d=s.index('.')                                       #方法一
    dict={'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9 }
    m=reduce(lambda x, y: x*10+y, list(map(lambda x:dict[x],s[:d])))+0.1*reduce(lambda x, y: x/10+y, list(map(lambda x:dict[x],s[:len(s)-d-1:-1])))
    return m


# 测试:
print('str2float(\'123.456\') =', str2float('123.456'))
if abs(str2float('123.456') - 123.456) < 0.00001:
    print('测试成功!')
else:
    print('测试失败!')
# -*- 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 str2num(s):
        return DIGITS[s]
    def sum(x, y):
        return x * 10 + y
    n = s.index('.')
    s1 = reduce(sum, map(str2num, s[:n]))
    s2 = reduce(sum, map(str2num, s[n+1:])) / 10 ** (len(s) - n - 1)
    return s1 + s2

#测试
print('str2float(\'123.456\') =', str2float('123.456'))
if abs(str2float('123.456') - 123.456) < 0.00001:
    print('测试成功!')
else:
    print('测试失败!')
# -*- coding: utf-8 -*-
from functools import reduce

def str2float(s):            #方法三
    def charToInt(ch):
        DIGITS={'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}
        return DIGITS[ch]
    nums=s.split('.')#分割整数和小数部分
    res1 = reduce(lambda x,y:x*10+y,map(charToInt,nums[0]))#整数部分转成数字
    res2=reduce(lambda x,y:x*10+y,map(charToInt,nums[1]))#小数部分转成数字
    return res1+(res2)/(10**len(nums[1]))#整数+小数部分除以数量级即可


#测试
print('str2float(\'123.456\') =', str2float('123.456'))
if abs(str2float('123.456') - 123.456) < 0.00001:
    print('测试成功!')
else:
    print('测试失败!')

# -*- coding: utf-8 -*-
from functools import reduce

def str2float(s):                  #方法四
    tmp = s.find('.')
    s1 = s[:tmp]
    s2 = s[tmp+1:]
    s1 = list(map(int, s1))
    s2 = list(map(int, s2))
    s2 = s2[::-1]
    tmp1 = reduce(m1, s1)
    tmp2 = reduce(m2, s2)
    return tmp1 + tmp2*0.1

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

def m2(x, y):
    return x * 0.1 + y


#测试
print('str2float(\'123.456\') =', str2float('123.456'))
if abs(str2float('123.456') - 123.456) < 0.00001:
    print('测试成功!')
else:
    print('测试失败!')
# -*- 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}
    n = s.index('.') #小数点位置
    def integ(x, y):#学到原来传参不需要按上一个函数的参数,
        return 10 * x + y  #整数部分运算
    def decimal(x, y):
        return 0.1 * x + y  #小数部分
    def char2num(s):
        return DIGITS[s]
    s1 = list(map(char2num, s[:n]))  #分离出整数部分的列表
    s2 = list(map(char2num, s[n+1:]))#分离出小数部分的列表
    s2 = s2[::-1]  #方便运算,将小数部分列表顺序倒转,切片
    return reduce(integ, s1) + 0.1 * reduce(decimal, s2)
    #注意输出时小数部分为4.56,应再乘上0.1方能得到正确答案

#测试
print('str2float(\'123.456\') =', str2float('123.456'))
if abs(str2float('123.456') - 123.456) < 0.00001:
    print('测试成功!')
else:
    print('测试失败!')

注解一些方法帮助理解和运用:

  1. str.index(str,beg=0,end=len(string))
    参数: str----指定检索的字符串
    beg—开始索引,默认为0
    end–结束索引,默认为字符串的长度
    返回值:如果包含子字符串返回开始的索引值,否则抛出异常
    同find()方法一样,但找不到会报错

fliter()

Python内建的filter()函数用于过滤序列。
简单的运用lambda表达式和filter()
在这里插入图片描述
再做一次求素数:

# 用filter求素数,埃氏筛法。
#生成器 _odd_iter(),是一个无限序列
def _odd_iter():
    n = 1
    while True:
        n = n + 2
        yield n
# 筛选函数
def _not_divisible(n):
    return lambda x: x % n > 0
#生成器
def primes():
    yield 2
    it = _odd_iter() # 初始序列
    while True:
        n = next(it) # 返回序列的第一个数
        yield n
        it = filter(_not_divisible(n), it) # 构造新序列
# 打印1000以内的素数:
for n in primes():
    if n < 1000:
        print(n)
    else:
        break

eg1

回数是指从左向右读和从右向左读都是一样的数,例如12321,909。请利用filter()筛选出回数:

# -*- coding: utf-8 -*-
def is_palindrome(n):
    return str(n) == str(n)[::-1]     #法一,也是最简单的一种方法



# 测试:
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('测试失败!')

sorted()

Python内置的sorted()函数就可以对list进行排序
sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序
sorted() 函数对所有可迭代的对象进行排序操作,key 是用来进行比较的元素。
key=lambda 元素: 元素[字段索引]
[0]按照第一维排序,[2]按照第三维排序
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值