Python——高阶函数

一 什么是高阶函数
——实参是一个函数名
——或者函数的返回值是一个函数
1)函数本身也可以赋值给变量,即:变量可以指向函数

 print(abs(-10))
f = abs
print(f(-10))

2)传递的参数包含函数名

def fun(x,y, f):
    return f(x), f(y)

print(fun(-10, 34, abs))

二 内置高阶函数
map 函数

#map
import random
print(list(map(abs,[-2,34,-54])))
def factorial(x):#求阶乘
    res=1
    for i in range(1,x+1):
        res=res*i
    return res
li=[random.randint(2,7) for i in range( 10)]
print(list(map(factorial,li)))

map函数是依次对序列调用函数的
reduce函数

#reduce
from functools import reduce
def multi(x,y):
    return x*y
#[1,2,3]====>multi(multi(1,2),3)
print(reduce(multi,range(1,4)))

reduce函数是用来对数列依次作累积的
filter函数

#filter(筛选序列)
def isPrime(num): #判断是否为质数
    for i in range(2, num):
        if num % i == 0:
            return  False
    else:
        return True
print(list(filter(isPrime,range(1,101))))

filter函数时对序列来进行筛选的
sort和sorted函数
1)li.sort()和sorted()两种方法的区别:
列表里面提供了sort方法, 其他数据结构没有.sorted方法可以对任何可迭代对象排序
sort方法支持原地排序(变量排序后, 变量本身改变), sorted排序后返回一个新的列表,并不改变原变量的内容
2)默认sort和sorted方法由小到大进行排序, reverse=True时, 由大到小进行排序

li = [1,2,6,21324,67,2,23]
print(sorted(li, reverse=True))

reverse=True时,排序由大到小进行排序
3)对于列表里面嵌套列表进行排序
sorted的key=用法:

info = [
    # 商品名称  数量  价格
    ('apple3', 200, 32),
    ('apple4', 40, 12),
    ('apple1', 40, 2),
    ('apple2', 1000, 23)
]
print(sorted(info))
#按照商品数量从小到大进行排序
def sorted_by_count(x):  #x =('apple3', 200, 32)
    return x[1]
print(sorted(info,key=sorted_by_count))   #key代表排序的关键字
#按照商品价格从小到大进行排序
def sorted_by_price(x):
    return x[2]
print(sorted(info,key=sorted_by_price))
#先按照商品数量从小到大进行排序,再按照商品价格从大到小进行排序(数量相等,价格大者优先)
def sorted_by_count_price(x):
    return x[1],-x[2]
print(sorted(info,key=sorted_by_count_price))

sorted的key=后面接的是函数,因此需要定义一个函数,但是显得有点过于冗长,如何来解决呢,这里引入匿名函数
lambda匿名函数

#lambda匿名参数
print(sorted(info,key=lambda x:x[1]))
print(sorted(info,key=lambda x:x[2]))
print(sorted(info,key=lambda x:(x[1],x[-2])))

可以看到代码量瞬间减少好多,其实还有一个方法
导入itemgetter函数

# #itemgetter
from operator import itemgetter
print(sorted(info,key=itemgetter(1)))
print(sorted(info,key=itemgetter(2)))
print(sorted(info,key=itemgetter(1,-2)))

和lambda函数一样简单,快捷
4)对于字典里面嵌套字典进行排序

d = {
    '003':{
        'name':'apple1',
        'count':100,
        'price':10
    },
    '002': {
        'name': 'apple1',
        'count': 200,
        'price': 2
    },
}
print(d.items())
print(sorted(d.items(),key=lambda x:x[1]['count']))   #此处若要反转,可以加上reverse=True
print(sorted(d.items(),key=lambda x:x[1]['price']))

# print(sorted(d.items(),key=itemgetter((1),'count')))   #这里不可以
print(sorted(d.values(),key=itemgetter('count')))

lambda函数和itemgetter函数都可以对字典进行排序
5)有一个整数列表(10个元素),要求调整元素顺序(偶数在前,奇数在后)

import random
li=[random.randint(1,10)for i in range(10)]
print(li)
print(sorted(li,key=lambda x:0 if x%2==0 else 1))  #使得 x%2==0 时为0,否则为1  再从小到大排序,0始终比1小,就使得偶在前,奇在后
print(sorted(li,key=lambda x:not x%2==0))   # 如果 x%2==0 时,为True,True=1 再not反转

这里利用0与1,巧妙的对奇偶数进行排序
三 min和max函数
min和max函数也拥有key=方法

l = ['hello', 'a', 'hjded', 'dederfref']

print(max(l, key=lambda  x: len(x)))
print(min(l, key=lambda  x: len(x)))

寻找最长的元素和最短的元素
四 协同推荐算法的实现
需求:
假设已有若干用户名字及其喜欢的电影清单,
现有某用户, 已看过并喜欢一些电影, 现在想找
新电影看看, 又不知道看什么好.
思路:
根据已有数据, 查找与该用户爱好最相似的用户,
即看过并喜欢的电影与该用户最接近,
然后从那个用户喜欢的电影中选取一个当前用户还没看过的电影进行推荐

# 1. 随机生成电影清单
import random

data = {}
for userItem in range(10):
    files = set([])
    for fileItem in range(random.randint(4, 15)):
        files.add("film" + str(fileItem))
    data["user" + str(userItem)] = files
print(data)

# 2. 查找与当前用户喜欢电影最相似的用户
user = {'file1', 'film4'}
# [(key, value), ()]
similarUser, films = max(data.items(), key=lambda x: x[1] & user)
print(similarUser, films)

print("待测用户喜欢的电影:", user)
print("推荐的电影:", films - user)

寻找与user用户交集最多的用户,来实现观影喜好相同,从而从此用户喜欢的电影里面取出user没有看过的,完成推荐
五 题目描述: 密码要求
1.长度超过8位
2.包括大小写字母.数字.其它符号,以上四种至少三种
3.不能有相同长度超2的子串重复
说明:长度超过2的子串

def checklen(s):
    if len(s) > 8:#判断密码长度是否达到8位,如果达到,返回True,否则,返回False
        return True
    else:
        return False

def check2(s):
    flag_up, flag_low, flag_digit, flag_other = 0, 0, 0, 0
    for i in s:#判断是否是由大小写字母,数字和特殊字符四种其中三种以上组成,
        if i.isupper():
            flag_up = 1
        elif i.islower():
            flag_low = 1
        elif i.isdigit():
            flag_digit = 1
        else:
            flag_other = 1
    #若有则+1,再将类型相加看是否大于等于3
    if (flag_up + flag_low + flag_digit + flag_other) >= 3:
        return True
    else:
        return False

def check3(s):#假设密码长度位8,那么i的值就是0~4,
    for i in range(len(s) - 3):
        if s.count(s[i:i + 3]) > 1:  #统计i,i+1,i+2三位是否有相同元素的数量大于1,来避免相同长度超过2的字符串重复
            return False
    return True

while True:
    s = input('Please enter your passwd:')
    if s == 'quit':#如果为空,则密码无效
        print("Ineffective passwd,Please again")
    if checklen(s) and check2(s) and check3(s):
        print("Successful!")#如果符合三种要求,就成功设置密码,并退出
        break
    else:
        print("Ineffective passwd,Please again")

这里写图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42668123/article/details/81807029