Python函数05/内置函数/闭包
内容大纲
1.内置函数(二)
2.闭包
1.内置函数(二)
#(abs()) 绝对值--返回的都是正数
#print([abs(i) for i in lst])
#enumerate -- 枚举("可迭代对象","序号的起始值")
#[(0,1),(1,2),(2,3)]
#print([i for i in enumerate(lst,10)])
# lst = [11,22,33,-44,23,21]
# new_lst = []
# for i in enumerate(lst):
# new_lst.append(i)
# print(new_lst)
# print([i for i in enumerate(lst,1000)])
# print(max([1,2,3,4,56,7,8])) # 求最大值
# print(min([1,2,3,4,-56,7,8])) # 求最小值
# print(sum([1,2,3,4,5],100)) # 求和
range
Python3:
g = range(0,10) 可迭代对象
g.__iter__()
Python2:
range(0,10) 获取是一个列表
xrange(0,10) 获取是一个可迭代对象
# from collections import Iterable,Iterator
# print(isinstance(g,Iterable))
# print(isinstance(g,Iterator))
print(sep=" ",end="
")
print(1,2,3,sep=" ") sep多个元素的连接符
# print(1,end=" ") " "制表符是四个空格
# print(2,end=" ")
# print(3)
# print(12345,file=open("t1.txt","w",encoding="utf-8"))
# print(list("alex")) #['alex',]
# print(dict(key=1,a="alex"))
# print(dict(((1,2),(2,3),(3,4))))
# print(dict([i for i in enumerate(range(20),1)]))
# zip() # 拉链 -- 按照最少的进行合并
#print(dir(list)) 查看当前函数的方法
面试题
lst1 = [1,2,3,4,5]
lst2 = ['a','b','c']
print(dict(list(zip(lst1,lst2))))
print(dict(zip(lst1,lst2)))
2.匿名函数及内置函数(重要)
# def func():
# print(123)
# return "你好"
# func()
# def func(a,b):
# return a+b
# print(func(1,2))
匿名函数:
f = lmabda x,y:(x,y)
print(f(1,2))
print(f.__name__)
# def func():
# return 1
# print(func())
print((lambda x:x)(2)) #同一行定义 同一行调用
lambda 关键字--定义函数
x,y 形参
x+y 返回值--只能返回一个数据类型
lst = [lambda i:i*i for i in range(10)]
print(lst[2](2))
lst = []
for i in range(10):
def func(i):
return i*i
lst.append(func)
print(lst[2](2))
lst = [lambda :i*i for i in range(10)]
print(lst[2]())
for i in range(10)
pass
print(i)
lst = []
for i in range(10):
def func():
return i*i
lst.append(func)
print(lst[2]())
一行函数
形参可以不写
返回值必须要写,返回值只能返回一个数据类型
lst = list((lambda i:i*i for i in range(5)))
print(lst[1](4))
结果:16
lst = [x for x in (lambda :i**i for i in range(5))]
print(lst[2]())
结果:256
lst1 = []
def func():
for i in range(5):
def foo():
return i**i
yield foo
for x in func():
lst1.append(x)
print(lst1[2]())
# 内置函数(重要)
# print(format(13,">20")) # 右对齐
# print(format(13,"<20")) # 左对齐
# print(format(13,"^20")) # 居中
# print(format(13,"08b")) # 二进制
# print(format(13,"08d")) # 十进制
# print(format(13,"08o")) # 八进制
# print(format(12,"08x")) # 十六进制
# print(bin(13))
filter() # 过滤
lst = [1,2,3,4,5]
def func(s):
return s > 3
print(list(filter(func,lst)))
func就是自己定义一个过滤条件,lst要迭代的对象
lst = [1,2,3,4,5,6,7]
print(list(filter(lambda x:x % 2 == 1,lst)))
map() 对象映射
print(list(map(lambda x:x*x,[1,2,3,4,5]))
将可迭代对象中的每一个元素进行加工
反转
lst = [1,2,3,4,5]
lst.reverse()
print(lst)
lst1 = list(reversed(lst))
print(lst)
print(lst1)
# lst = [1,23,34,4,5,213,123,41,12,32,1]
print(sorted(lst) #升序
print(lst1)
# lst = [1,23,34,4,5,213,123,41,12,32,1]
print(sorted(lst,reverse=True)) #降序
dic = {"key":1,"key1":2,"key2":56}
print(sorted(dic,key=lambda x:dic[x],reverse=True))
key是指定排序规则
print(max([1,2,4,5],key=abs)) key是指定查找最大值的规则
from functools import reduce
reduce 累计算
print(reduce(lambda x,y:x+y,[1,2,3,4,5]
3.闭包
def func():
a = 1
def f1():
def foo():
print(a)
return foo
return f1
ret = func()
a = ret()
a()
func()()()
1.在嵌套函数内,使用非全局变量(且不是本层变量)--就是闭包
avg_lst = []
def func(price):
avg_lst.append(price)
avg = sum(avg_lst)/len(avg_lst)
return avg
print(func(150000))
print(func(160000))
print(func(170000))
print(func(150000))
avg_lst.append(188888)
#全局变量可能被修改
def func(price):
avg_lst = []
avg_lst.append(price)
avg = sum(avg_lst)/len(avg_lst)
return avg
print(func(150000))
print(func(160000))
print(func(170000))
print(func(150000))
#这样取不到平均值,每次都是每天的价钱
def func():
avg_lst = [] #自由变量
def foo(price):
avg_list.append(price)
avg = sum(avg_lst)/len(avg_lst)
return avg
return foo
ret = func()()
# __closure__ 判断是否是闭包
# 了解:
# print(ret.__code__.co_freevars) # 获取的是自由变量
# print(ret.__code__.co_varnames) # 获取的是局部变量
# 闭包的作用:
# 1. 保证数据的安全性
# 2. 装饰器
4.今日总结
# 1.内置函数二:
# 1.1 匿名函数 lambda
# lambda 形参:返回值 - lambda x:x
# 形参可以不写,返回值必须写 返回值只能是一个数据类型
# 匿名函数的名字叫做 lambda
# 1.2 abs() 绝对值
# 1.3 filter("函数名","可迭代对象") 写函数的时候可以指定过滤条件
# 1.4 map("函数名","可迭代对象") 写函数的时候可以指定对元素的操作
# 1.5 list(zip("可迭代对象","可迭代对象")) 返回的是[(1,2),(2,3)]
# 1.6 sorted("可迭代对象",key="函数名",reverse=True) key是指定排序的规则(默认是升序)写了reverse=True就是降序
# 1.7 reversed("可迭代对象") # 对可迭代对象进行翻转(不改变源数据)
# 1.8 max("可迭代对象",key=abs) #key指定查找最大值时的规则
# 1.9 min("可迭代对象",key=abs) #key指定查找最小值时的规则
# 1.10 sum(list,tuple,set)
# 1.11 reduce("函数","可迭代对象") # 函数指定累计算的方式
# 1.12 format()
# 08b -- 2
# 08d -- 10
# 08o -- 8
# 08x -- 16
# 2.闭包:
# 啥是闭包:嵌套函数内,使用非全局变量就是闭包
# 闭包干啥:保证数据的安全性,装饰器使用
5.今日练习
注意重要内置函数的使用,注意哪些打印的时候需要在外面加list
# 1.将今日课上的代码敲3遍。
# 2.都完成的做一下作业(下面题都是用内置函数或者和匿名函数结合做出):
#
# 1)用map来处理字符串列表,把列表中所有人都变成sb,比方alex_sb
# l=[{'name':'alex'},{'name':'y'}]
# print(list(map(lambda x:{'name':x['name']+"_sb"},l)))
# 2)用map来处理下述l,然后用list得到一个新的列表,列表中每个人的名字都是sb结尾
# l=[{'name':'alex'},{'name':'y'}]
# print(list(map(lambda x:(x['name']+"sb"),l)))
# 3)用filter来处理,得到股票价格大于20的股票名字
# shares={
# 'IBM':36.6,
# 'Lenovo':23.2,
# 'oldboy':21.2,
# 'ocean':10.2,
# }
# print(list(filter(lambda x:shares[x]>20,shares)))
# 4)有下面字典,得到购买每只股票的总价格,并放在一个迭代器中。
# 结果:list一下[9110.0, 27161.0,......]
# portfolio = [
# {'name': 'IBM', 'shares': 100, 'price': 91.1},
# {'name': 'AAPL', 'shares': 50, 'price': 543.22},
# {'name': 'FB', 'shares': 200, 'price': 21.09},
# {'name': 'HPQ', 'shares': 35, 'price': 31.75},
# {'name': 'YHOO', 'shares': 45, 'price': 16.35},
# {'name': 'ACME', 'shares': 75, 'price': 115.65}]
# #
# print(list(map(lambda x:x['shares']*x['price'],portfolio)))
# 5)还是上面的字典,用filter过滤出单价大于100的股票。
# print(list(filter(lambda x:x['price']>100,portfolio)))
#
# 6)有下列三种数据类型,
# l1 = [1,2,3,4,5,6]
# l2 = ['oldboy','alex','wusir','太白','日天']
# tu = ('**','***','****','*******')
# 写代码,最终得到的是(每个元祖第一个元素>2,第三个*至少是4个。)
# [(3, 'wusir', '****'), (4, '太白', '*******')]这样的数据。
# print(list(zip(l1,l2,tu))[2:])
# print(list(filter(lambda x:x[0]>2 and len(x[2])>=4,list(zip(l1,l2,tu)))))
# 7)有如下数据类型(实战题):
#
# l1 = [ {'sales_volumn': 0},
# {'sales_volumn': 108},
# {'sales_volumn': 337},
# {'sales_volumn': 475},
# {'sales_volumn': 396},
# {'sales_volumn': 172},
# {'sales_volumn': 9},
# {'sales_volumn': 58},
# {'sales_volumn': 272},
# {'sales_volumn': 456},
# {'sales_volumn': 440},
# {'sales_volumn': 239}]
# 将l1按照列表中的每个字典的values大小进行排序,形成一个新的列表。
# print(sorted(l1,key=lambda x:x['sales_volumn']))
# 3.有如下数据结构,通过过滤掉年龄大于16岁的字典
# 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']<=16,lst)))
# 4.有如下列表,按照元素的长度进行升序
# lst = ['天龙八部','西游记','红楼梦','三国演义']
# print(sorted(lst,key=lambda x:len(x)))
# 5.有如下数据,按照元素的年龄进行升序
# 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']))
# 6.看代码叙说,两种方式的区别
# lst = [1,2,3,5,9,12,4]
# lst.reverse()
# print(lst)
# 改变原列表
# print(list(reversed(lst)))
# 没有对原列表改变,只是新开的空间做的改变
# 7.求结果(面试/题)
v = [lambda :x for x in range(10)]
print(v) #10个生成器函数的内存地址
print(v[0]) #第一个生成器函数的内存地址
print(v[0]()) #9
# 8.求结果(面试题)
# v = (lambda :x for x in range(10))
# print(v) #生成器的内存地址
# print(v[0]) #报错
# print(v[0]()) #报错
# print(next(v)) #生成器后面第一个函数的内存地址
# print(next(v)()) #0
# 9.map(str,[1,2,3,4,5,6,7,8,9])输出是什么? (面试题)
# map函数的内存地址(没有加list)
除了sorted reduce不需要加list 其余filter map reversed等都需要加list
10.有一个数组[34,1,2,5,6,6,5,4,3,3]请写一个函数,找出该数组中没有重复的数
的总和(上面数据的么有重复的总和为1+2=3)(面试题)
lst = [34,1,2,5,6,6,5,4,3,3]
print(sum(list(filter(lambda x:lst.count(x)==1,lst)))) #使用count
11.求结果:(面试题,比较难,先做其他题)
def num():
return [lambda x:i*x for i in range(4)]
print([m(2)for m in num()])
[6, 6, 6, 6]
def num():
return (lambda x:i*x for i in range(4))
print([m(2)for m in num()])
[0,2,4,6]