推导式、内置函数、高阶函数、匿名函数

  1、推导式:做一些有规律的数据结构

列表推导式:

      普通循环模式:

      [加工后的变量 for 循环]

      示例一:print([i for i in range(1,51)])
      结果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
      示例二:print([i for i in range(1,51,2)])
      结果:[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49]
      格式化:
      print([f"python{i}期" for i in range(1,51)])
      筛选模式:
      [加工后的变量 for循环 加工条件]
      print([i for i in range(1,51) if i > 25])
      结果:[26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
for循环两个数的和:
lst = []
for i in range(2):
  for j in range(2):
    lst.append(i+j)
print(lst)
结果:[0, 1, 1, 2]
列表推导式两个数的和(推导式最多建议使用三层):
print([i + j for i in range(2) for j in range(2)])
结果:[0, 1, 1, 2]
字典推导式:
print({i:i+1 for i in range(3)})
结果:{0: 1, 1: 2, 2: 3}
集合推导式:
print({f"{i}:{i+1}" for i in range(3)})
结果:{'1:2', '0:1', '2:3'}
{加工后的变量:加工后的变量 for循环 加工条件}
print({i:i+1 for i in range(3) if i >= 0})
结果:{0: 1, 1: 2, 2: 3}
推导式:用在哪?简化代码、提高可读性
生成一些有规律的数据、生成的数据较大时建议使用生成器推导式
for循环索引推导式:
s = "alex,meet"
count = 0
for i in s:
if i == "e":
print(count)
count += 1
结果:2
   6
   7
len索引推导式:
print([i for i in range(len(s)) if s[i] == "e"])
列表嵌套推导式:
names = [['Tom','Billy','Jefferson','Andrew','Wesley','Steven','Joe'],
['Alice','Jill','Ana','Wendy','Jennifer','Sherry','Eva']
]
写法一:
for i in names:
for em in i:
if "e" in em:
print(em)
写法二:
print([em for i in names for em in i if "e" in em])
偶数推导式:
print([i for i in range(30) if i % 3 is 0])
结果:[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
过滤和转大写:
l = ['wusir','laonanhai','aa','b','taibai']
print([i.upper() for i in l if len(i) > 3])
结果:['WUSIR', 'LAONANHAI', 'TAIBAI']
2、生成器表达式和列表推导式的语法上一模一样、只是把[]换成()就行了、例如将10以内所有数的平方放到一个生成器表达式中:
gen = (i**2 for i in range(10))
print(gen)               #得到生成器对象
print(gen.__next__())        #生成一个数
print(next(gen))           #再次生成一个数
生成器表达式进行筛选:
gen = (i for i in range(1,100) if i % 3 == 0)
for num in gen:
print(num)
3、生成器表达式和列表推导式的区别?
列表推导式比较耗内存、所有数据一次性加载到内存、而生成器表达式遵循迭代器协议、逐个产生元素。
得到的值不一样、列表推导式得到的是一个列表、生成器表达式获取的是一个生成器
列表推导式一目了然、生成器表达式只是一个内存地址
无论是生成器表达式还是列表推导式、只是python提供了一个相对简单的构造方式、因为使用推导式非常简单、推导式只能构建相对复杂的并且有规律的对象
对于没有什么规律、而且嵌套层数比较多不建议使用推导式构建
生成器的惰性机制:生成器只有在访问的时候才取值、
4、内置函数:python写了很多功能避免重复造轮子
一带而过:
all()  #判断元素是否都为true
any()  #判断元素是否有一个是true就是true
bytes() #字符串转字节
callable("你好")  #判断是否可调用
chr()  #根据当前编码查看对应的内容
complex()  #查看复数
divmod()  #获取是元组、第一个是商、第二个是余数
eval()  #禁用
exec()  #禁用
frozenset()  #冻结集合
globals()
hash()  #有值是不可变的数据类型
help()  #查看方法的帮助信息
id()   
input()
int()
iter()
locals()
next()
oct()  #十进制转成八进制
bin()  #十进制转成二进制
hex()  #十进制转成十六进制
print(int("0x1e",16))  #十六进制转成十进制
ord()  #根据值查看当前编码
pow()  #幂
repr()  #原形毕露
round()  #保留小数位
重点记住:
abs()  #绝对值
format()  #格式化
enumerate()  #枚举、自动获取元素下标、自动计数
filter()
map()
max()
min()
open()
range()
print()
len()
list()
dict()
str()
float()
reversed()
set()
sorted()  #排序
sum()
tuple()
type()
zip()
dir()  #查看当前对象都有什么方法
未来会用:
classmethod()
delattr()
getattr()
hasattr()
issubclass()
isinstance()
object()
property()
selattr()
staticmethod()
super()
5、高阶函数:
filter(规则函数,可迭代对象)、
map(规则函数,可迭代对象,可迭代对象)、
max()、
min()、
reversed(可迭代对象)、
sorted(可迭代对象,key = 规则函数)、
reduce(累加函数,可迭代对象)、
zip()、
6、匿名函数,顾名思义就是没有名字的函数,那么什么函数没有名字呢?这个就是我们以后面试或者工作中经常用匿名函数 lambda,也叫一句话函数。
现在有一个需求:你们写一个函数,此函数接收两个int参数,返回和值。
def func(a,b):
    return a+b
print(func(3,4))
那么接下来我们用匿名函数完成上面的需求:
func = lambda a,b: a+b
print(func(3, 4))  # 7
语法:

​ 1)此函数不是没有名字,他是有名字的,他的名字就叫做lambda

​ 2)lambda 是定义匿名函数的关键字,相当于函数的def.

​ 3)lambda 后面直接加形参,形参加多少都可以,只要用逗号隔开就行。  

​ 4)返回值在冒号之后设置,返回值和正常的函数一样,可以是任意数据类型。(但是想要返回多个元素要以容器的形式返回)

​ 5)匿名函数不管多复杂.只能写一行.且逻辑结束后直接返回数据

写匿名函数:接收一个可切片的数据,返回索引为0与2的对应的元素(元组形式)。

func = lambda x:(x[0],x[2])
print(func('afafasd'))
7、匿名函数三元表达式:
func = lambda x,y: x if x > y else y
print(func(3,100))
结果:100
8、匿名函数lambda和有名函数def:
f = lambda a,b:a + b
print(f(1,2))
# 结果3
def func(a,b):
c = a + b
return c
print(func(1,2))
# 结果3
lambda和def是一样的、
a,b和(a,b)是一样的
:a + b和return a + b是一样的
冒号前面叫做形参、冒号后面叫做返回值
形参可以接受位置参数、动态位置、默认、动态关键字参数、形参不可不写
返回值只能返回一个数据、返回值必须写
返回值是多个时用括号包起来
print(f.__name__)--查看函数名
9、lambda函数举例:
# g = [lambda i:i+1 for i in range(3)]  #首先这是列表推导式、循环三圈得到三个匿名函数lambda、例如定义是L、第二圈还是L、第三圈还是L、函数体中存的是代码、也可以把for i定义成for j、整个推完之后有三个函数的内存地址定义为g、
# print([em(3) for em in g])         #然后循环三个内存地址定义em、加括号运行、命名参数3、得到结果3+1=4、第二圈还是4、第三圈还是4
#上面两行代码拆解:
lst = []
for i in range(3): #for循环0到3
def func(i): #形参是i也就是0、1、2
return i + 1 #返回值是循环的每个值加1
lst.append(func) #往空列表里面增加func函数的内存地址
print(lst) #打印出lst列表里面的3个func函数的内存地址
# 结果:[<function func at 0x00000000001E2EA0>, <function func at 0x0000000001E9AB70>, <function func at 0x0000000001E9AA60>]

new_lst = [] #新建空列表new_lst
for em in lst: #循环lst列表里面的3个func函数的内存地址
new_lst.append(em(3)) #空列表里面增加3个func函数的内存地址运行结果、说白了在调用func、但是func函数需要参数i、所以增加em里面增加一个参数3
print(new_lst) #打印new_lst列表
# 结果:[4, 4, 4]
10、lambda函数举例二:
# g = (lambda i:i+1 for j in range(3))
# print([em(3) for em in g])
#上面两行代码拆解:
def foo():
for j in range(3):
def func(i):
return i + 1
yield func
g = foo()
# print(g) #得到生成器
# print(next(g)) #得到函数的内存地址

lst = []
for i in g:
lst.append(i(3))
print(lst)
结果:[4,4,4]
11、小括号是生成器推导式、中括号是列表推导式
12、lambda函数举例三:
# g = [lambda :i+1 for i in range(3)]
# print([em() for em in g])
#上面两行代码拆解:
g = []
for i in range(3):
def func():
return i + 1
g.append(func)
print(g)

new_lst = []
for em in g:
new_lst.append(em())
print(new_lst)
结果:[3,3,3]
13、lambda函数举例四:
g = (lambda :i+1 for i in range(3))
print([em() for em in g])
#上面两行代码拆解:
def foo():
for i in range(3):
def func():
return i + 1
yield func
g = foo()

lst = []
for i in g:
lst.append(i())
print(lst)
结果:[1,2,3]
14、lambda函数举例五:
g = [lambda x:x*i for i in range(3)]
for j in [2,10]:
g1 = (em(3) for em in g)
print([e+j for e in g1])
结果:[16, 16, 16]
15、lambda函数举例六:
lst = []    #[func,func,func]
for i in range(3):
def func(x):
return x * i #3*2
lst.append(func)

for j in [2,10]:
def g1(): #循环产生两个生成器、第二个生成器10覆盖第一个的2
for em in lst:
yield em(3) #func(3)

new_lst = []
for e in g1():
new_lst.append(e + j) #g1是6、e是6、j是10
print(new_lst)
# 结果:[16, 16, 16]
16、模拟高阶函数filter过滤:
filter函数是把列表中的值所有的都筛选一遍最后在得到一个值(列表)
lst = [1,2,3,4,54,65,7,8]
def foo(x): #规则函数
return x > 4 #判断的是True和False

def f(func,iter): #filter
lst = [] #[54,65,7,8]
for i in iter:
if func(i):
lst.append(i)
return lst
print(f(foo,lst))
# 结果:[54, 65, 7, 8]
17、高阶函数filter:
lst = [1,2,3,4,54,65,7,8]
print(list(filter(lambda x:x > 4,lst)))
18、#过滤掉年龄大于等于17的
lst = [{'id':1,'name':'alex','age':18},
{'id':1,'name':'wusir','age':17},
{'id':1,'name':'taibai','age':16},]
print(list(filter(lambda x:x["age"] >= 17,lst)))
结果:[{'id': 1, 'name': 'alex', 'age': 18}, {'id': 1, 'name': 'wusir', 'age': 17}]
19、过滤掉名字长度大于等于5的(过滤出是拿到、过滤掉是不要)
lst = [{'id':1,'name':'alex','age':18},
{'id':1,'name':'wusir','age':17},
{'id':1,'name':'taibai','age':16},]
print(list(filter(lambda x:len(x["name"]) >= 5,lst)))
# 结果:[{'id': 1, 'name': 'wusir', 'age': 17}, {'id': 1, 'name': 'taibai', 'age': 16}]
20、高阶函数map映射--将可迭代对象中每个元素执行函数功能:
map函数是装一个列表依次处理得到的还是一个列表,跟原先的列表顺序一样、只不过每个元素被处理了
转成字符串:
lst = [1,2,3,4,5,6,8,9]
print(list(map(str,lst)))
# 结果:['1', '2', '3', '4', '5', '6', '8', '9']
合并求列表和:
lst1 = [1,2,3]
lst2 = [3,2,1]
print(list(map(lambda x,y:x + y,lst1,lst2)))
结果:[4, 4, 4]
21、sorted排序函数:
lst = [1,2,3,4,65,7]
print(sorted(lst)) #新建列表
结果:[1, 2, 3, 4, 7, 65]

lst.sort()
print(lst) #原地修改
结果:[1, 2, 3, 4, 7, 65]
print(sorted("alex,mdsb"))              #升序
结果:[',', 'a', 'b', 'd', 'e', 'l', 'm', 's', 'x']
print(sorted("alex,mdsb",reverse=True)) #降序
结果:[',', 'a', 'b', 'd', 'e', 'l', 'm', 's', 'x']
排键:
dic = {1:"a",3:"c",2:"b"}
print(sorted(dic))
结果:[1, 2, 3]
四大名著排序:
lst = ['天龙八部','西游记','红楼梦','三国演义']
print(sorted(lst,key = len)) #key = 排序规则
结果:['西游记', '红楼梦', '天龙八部', '三国演义']
lst = [{'id':1,'name':'alex','age':18},
{'id':2,'name':'wusir','age':17},
{'id':3,'name':'taibai','age':16},]
print(sorted(lst,key=lambda x:x['age'],reverse=True))
# 结果:[{'id': 1, 'name': 'alex', 'age': 18}, {'id': 2, 'name': 'wusir', 'age': 17}, {'id': 3, 'name': 'taibai', 'age': 16}]
22、max最大值:
print(max([1,2,3,4,5,6,-9,10,-22],key=abs))
结果:-22
23、min最小值:
print(min([1,2,3,4,5,6,-9,10,-22],key=abs))
结果:1
24、reduce累计算:
reduce函数是可以把完整的序列合并到一块儿最终得到一个值
累乘:
from functools import reduce
lst = [1,2,3,4,5]
print(reduce(lambda x,y:x*y,lst))
结果:120
25、zip拉链:
lst1 = [1,2,3,4,5]
lst2 = [5,4,3,2,1]
print(list(zip(lst1,lst2)))
结果:[(1, 5), (2, 4), (3, 3), (4, 2), (5, 1)]
26、print加参数分隔符
print("alex","wusir","太亮",sep="|")
结果:alex|wusir|太亮
print("alex","wusir","太亮",sep="|",end="")
print("meet")
结果:alex|wusir|太亮meet
作业题:
三次登陆锁定:
"""
四.用代码实现三次用户登录及锁定(选做题,这是一个单独的程序)
项目分析:
一.首先程序启动,显示下面内容供用户选择:
1.注册
2.登录
a.用户选择登录的时候,首先判断用户名在userinfo.txt表中存在不在,存在就不能进行注册
b.当注册的用户名不存在的时候将用户名和密码写入到userinfo.txt文件中
c.用户选择登录的时候,判断用户输入的账号和密码是否userinfo.txt存储的一致
d.用户名和密码一致就终止循环,并提示用户登录成功!
e.用户名和密码不一致,只有三次登录机会,三次过后提示用户名被锁定,请联系管理员!并终止循环
f.当用户名错误三次,再次运行程序.登录锁定的账号继续提示用户名被锁定,请联系管理员!
"""
# 结束标识
quite_flag = False # ------------------------------2、

# 错误登录次数 #------------------------------------3、
login_fail = 0

# 登录功能
def login(): # -----------------------------5、
"""
登录
:return:
"""
while True:
global login_flag # 定义全局登录状态
global quite_flag # 定义全局结束标识
global login_fail # 定义全局登录次数
user_name = input ( "请输入登录用户名:" )
password = input ( "请输入密码:" )
if user_name in userinfo_dic:
login_flag = True if password == userinfo_dic[user_name] else False
if userinfo_dic[user_name + "locked"] == "True":
login_flag = False
print ( "用户名被锁定,请联系管理员!" )
break
if login_flag:
print ( "登陆成功!" )
quite_flag = True
break
else:
login_fail += 1
if login_fail == 3:
modif_userinfo(user_name,userinfo_dic[user_name],str(True))
quite_flag = True
print("用户名被锁定,请联系管理员!")
break
else:
print("用户账号或密码错误,请重新输入")
else:
print("用户名不存在!请重新输入!")



# 注册功能
def register():
"""
注册
:return:
"""
while True:
user_name = input ( "请输入用户名(不能有特殊字符):" )
password = input ( "请输入密码长度要在6~14个字符之间:" )
if user_name not in userinfo_dic:
if user_name.isalnum () and 5 < len ( password ) < 15:
write_userinfo ( user_name, password )
print ( "注册成功!" )
global login_fail # 声明全局错误登录次数
login_fail = 0
global login_flag # 声明全局登录状态
login_flag = True #改成登录状态True
break #改成break相当于注册完毕了
else:
print ( "输入错误,请重新输入" )
else:
print ( "用户名已存在!请重新输入!" )


def quite():
"""
退出
:return:
"""
global quite_flag
quite_flag = True


# 定义用户读取文件信息功能
def read_userinfo(path_add: str):
"""
读取用户信息
:return:
"""
with open ( path_add, "a+", encoding="utf-8" ) as f:
global userinfo_dic
f.seek ( 0 )
for i in f:
if i != " " and i != "" and i is not None:
userinfo_dic[i.split ( ":" )[0].strip ()] = i.split ( ":" )[1].strip ()
userinfo_dic[i.split ( ":" )[0].strip () + "locked"] = i.split ( ":" )[2].strip ()


# 定义用户写入文件信息功能
def write_userinfo(user_name: str, password: str):
"""
写入用户信息
:param user_name:
:param password:
:return:
"""
with open ( path_add, "a", encoding="utf-8" ) as f1: #a模式、防止文件不存在时报错
f1.write ( f" {user_name}:{password}:False" ) #第一次注册往字典里面添加状态没有被锁定
f1.flush ()
global login_fail # 定义全局错误登录次数
userinfo_dic[user_name] = password # 字典是可变数据类型、在局部使用全局进行修改不用使用global、往字典里面增加键值对
userinfo_dic[user_name + "locked"] = str ( False ) # 往用户信息字典里面建立用户锁定状态


# 定义用户锁定信息功能
def modif_userinfo(user_name: str, password: str, locked: str):
"""
锁定用户信息修改
:param user_name:
:param password:
:param locked:
:return:
"""
with open ( path_add, "r", encoding="utf-8" ) as f4,
open ( path_add.replace ( ".txt", "1.txt" ), "w", encoding="utf-8" ) as f5:
for i in f4:
if i != " " and i.split ( ":" )[0].strip () == user_name:
i = f"{user_name}:{password}:{locked} "
f5.write ( i )
f5.flush ()
global userinfo_dic
userinfo_dic[user_name] = password
userinfo_dic[user_name + "locked"] = locked
import os
import time
os.rename ( path_add, path_add.replace ( ".txt", str ( time.time () ) + ".bak" ) )
os.rename ( path_add.replace ( ".txt", "1.txt" ), path_add )
global login_fail # 定义全局登录次数
login_fail = 0


# 组成字典容器
choose_dic = {"1": register,
"2": login,
}

# 新建已注册的用户账户和密码字典形式:
userinfo_dic = dict ()

# 定义文件地址信息存储位置变量
path_add = "userinfo_single.txt"

# 读取一下已经注册的用户和密码
read_userinfo ( path_add )

# 登陆信息提示:#-----------------------------------1、
print ( """1.注册
2.登录""" )

# 主程序 #---------------------------------------4、
while not quite_flag:
choose = input ( "请选择您要进行的操作对应的序号:" )
choose_dic[choose] () if choose in choose_dic else print ( "输入错误,请重新输入!" )
else:
print ( "结束" )
# 1、用列表推导式做下列小题
lst = ["alex","wusir","太白","宝元"]
# 过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
print([i.upper() for i in lst if len(i) > 3])
# 2、求[{x:y}]其中x是0-5之间的偶数组成的元组的,y是0-5之间的奇数组成的元组
print([{tuple([i for i in range(0,6,2)]):tuple([i for i in range(1,6,2)])}])
# 3、求3,6,9 组成的列表结果: M = [[1,2,3],[4,5,6],[7,8,9]]
print([[i for i in range(1,4)],[i for i in range(4,7)],[i for i in range(7,10)]])
# print([i-2,i-1,i] for i in [3,6,9])?????????????????????????这道题我不会做太难了
# 4、求出50以内能被3整除的数的平方,并放入到一个列表中。
print([i**2 for i in range(51) if i // 3])
# 5、构建一个列表:['python1期', 'python2期', 'python3期', 'python4期', 'python6期', 'python7期', 'python8期', 'python9期', 'python10期']
print(["python%s期" %i for i in range(1,11)])
# 6、构建一个列表:[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
# 7、构建一个列表:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
print([i for i in range(20) if i % 2 == 0])
# 8、有一个列表l1 = ['alex', 'WuSir', '老男孩', '太白']将其构造成这种列表
# ['alex0', 'WuSir1', '老男孩2', '太白3']
print(['%s%s' %(l1,i) for i,l1 in enumerate(l1)])
# for循环形式:
# l1 = ['alex','Wusir','老男孩','太白']
# for i,em in enumerate(l1):
# print(em + str(i))
# 9、有以下数据类型:
x = {
'name':'alex',
'Values':[{'timestamp':1517991992.94,
'values':100,},
{'timestamp': 1517992000.94,
'values': 200,},
{'timestamp': 1517992014.94,
'values': 300,},
{'timestamp': 1517992744.94,
'values': 350},
{'timestamp': 1517992800.94,
'values': 280}
],}
# 将上面的数据通过列表推导式转换成下面的类型:[[1517991992.94, 100], [1517992000.94, 200], [1517992014.94, 300], [1517992744.94, 350], [1517992800.94, 280]]
print([[i["timestamp"],i["values"]] for i in x["Values"]])
# 10、构建一个列表,列表里面是三种不同尺寸的T恤衫,每个尺寸都有两个颜色(列表里面的元素为元组类型)。
# colors = ['black', 'white']
# sizes = ['S', 'M', 'L']
print(list(zip(colors,sizes)))
# 11、构建一个列表,列表里面的元素是扑克牌除去大小王以后,所有的牌类(列表里面的元素为元组类型)。
# l1 = [('A','spades'),('A','diamonds'), ('A','clubs'), ('A','hearts')......('K','spades'),('K','diamonds'), ('K','clubs'), ('K','hearts') ]
# 12、看代码求结果(面试题):
# v = [i % 2 for i in range(10)]
# print(v)
# 结果:[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
# v = (i % 2 for i in range(10))
# print(v)
# 结果:<generator object <genexpr> at 0x0000000002152D00> #生成器内存地址
原文地址:https://www.cnblogs.com/zhang-da/p/11633267.html