python内置函数及匿名函数

时间:2022-03-08 21:14:40

locals  本地作用域/局部作用域 会随着位置的改变而改变
globals 全局作用域           永远不变 永远是全局

a = 1
b = 2
print(locals())
print(globals())
def func():
    c = 3
    d = 4
    print(locals())
def func2():
    l1 = []
    d1 = {}
    print(locals())     #无论在哪里打印 得到的都是全局作用域中的名字
func()
func2()
# 结果
# {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001CE3C83A470>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/PyPractise/day11.py', '__cached__': None, 'a': 1, 'b': 2}
# {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001CE3C83A470>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/PyPractise/day11.py', '__cached__': None, 'a': 1, 'b': 2}
# {'d': 4, 'c': 3}
# {'d1': {}, 'l1': []}

range(起始位置,终止位置,步长)
range(终止位置)
range(起始,终止位置)

range(5)  # 0,1,2,3,4
range(5, 0, -1)  # 5,4,3,2,1
range(1, 10, 2)  # 1,3,5,7,9

print(要打印的内容1,要打印的内容2,sep = '分隔符',end = '结束符',file=file.txt, flush=False)
file:  默认是输出到屏幕,如果设置为文件句柄,输出到文件
sep:   打印多个值之间的分隔符,默认为空格
end:   每一次打印的结尾,默认为换行符
flush: 立即把内容输出到流文件,不作缓存(默认缓存)
#print的本质,就是写文件,这个文件是pycharm的屏幕

print(123,'abc',sep='|',end='@')
print('www')
结果:
123|abc@www

事例二
f = open('file','w')
print(123,'abc',file=f,flush=True)
f.close()

案例:打印进度条
import time   #导入别人写好的代码
def func():
    for i in range(0,101,2):
        time.sleep(0.1)     #每一次在这个地方阻塞0.1s
        char_num = i//2     #控制输出长度
        if i == 100:
            per_str = '\r%s%% : %s\n' % (i, '*' * char_num)     # %% 转义%,\n换行符
        else:
            per_str = '\r%s%% : %s' % (i, '*' * char_num)
        print(per_str,end = '')     #per_str,end = ''格式化输出去除print末尾的默认换行符\n,不换行打印
func()
print('下载完成')

callable() 判断某一个变量是否可调用(True/False)

def call(arg):
    if callable(arg):
        arg()
    else:
        print('参数不符合规定')
def func():
    print('in func')
    return 1
func2 = 1234
call(func)
call(func2)
print(callable(func))
print(callable(func2))
结果
in func
参数不符合规定
True
False

round(小数,保留几位小数)  小数精确
整数是奇数 -> 正常四舍五入
整数是偶数 -> 五舍六入

2.x(完全的四舍五入)和3.x(更精准的计算方式)不同
print(round(2.3258358))
print(round(2.3253358,2))
print(round(2.3254358,3))
print(round(1.5))
print(round(2.5))
print(round(2.6))
结果
2
2.33
2.325
2
2
3

pow(x,y,z=1) 幂运算/幂余运算 x的y次方%z

print(pow(2,3))
print(pow(3,2))
print(pow(5,3,2))
print(pow(4,2,2))
print(pow(4,3,2))
结果
8
9
1
0
0

list
tuple

reversed  返回一个迭代器,节省内存
reversed 不修改原基础: 不直接返回列表而返回迭代器,为了不占用更多的内存
reverse 是在原基础上修改: 2000项的列表,不会产生额外的内存占用

l = [1,2]
l.reverse()
print(l)
结果:
[2, 1]

ret = reversed([1,2,3])  # iterator可迭代的
print(ret)
print(list(ret))
结果:
<list_reverseiterator object at 0x0000024B9ECEEC88>
[3, 2, 1]

lst = ["河南", "四川", "东北", "山东", "上海"]
r = reversed(lst)
print(list(r))
结果
['上海', '山东', '东北', '四川', '河南']

s= "不是上海自来水来自海上"
print(s[::-1])
it = reversed(s)
s2 = ''
for i in it:
    s2 += i
print(s2)
结果:
上海自来水来自海上是不
上海自来水来自海上是不

slice  切片

l = [1,2,3,4,5,]
ret = slice(1,4)   # [1:4]
print(l[ret])
等于
print(l[1:4])
结果:
[2, 3, 4]
[2, 3, 4]

format(填充)

print(format('test', '<20'),'alex')
print(format('test', '>20'),'alex')
print(format('test', '^20'),'alex')
结果:
test                 alex
                test alex
        test         alex

进制转换
print(format(3, 'b'))   # 转换成二进制  binary  0b11
print(format(65, 'c'))  # 转换成unicode字符  ascii
print(format(11, 'o'))  # 转换成八进制  0o    13
print(format(11, 'x'))  # 转换成十六进制(小写字母)
print(format(11, 'X'))  # 转换成十六进制(大写字母)
print(format(11, 'd'))  # 转换成十进制
print(format(11, 'n'))  # 和d一样
print(format(11))       # 和d一样
结果
11
A
13
b
B
11
11
11

科学计数法
print(format(123456789, 'e'))   # 科学计数法,默认保留6位小数,表示大的数据
print(format(123456789, '.2e')) # 科学计数法,保留2位小数(小写)
print(format(123456789, '0.2E'))# 科学计数法,保留2位小数(大写)
结果
1.234568e+08
1.23e+08
1.23E+08

浮点计数法
print(format(1.23456789, 'f'))    # 浮点数计数法,保留6位小数
print(format(1.23456789, '0.2f')) # 小浮点数计数法,保留2位小数
print(format(1, '0.10f'))         # 小浮点数计数法,保留10位小数
print(format(1.23456789e+10000, 'F')) # 小浮点数计数法
结果
1.234568
1.23
1.0000000000
INF        #无穷大

repr() 还原字符串最官方的效果

转义字符
\n 换行
\t tab 制表符
\r 回车
\"   双引号
\'  单引号
\\    \
print('hello\\n world')
结果
hello\n world

还原字符串最官方的效果
print(repr('hello\\n world'))
结果
'hello\\n world'

原封不动的显示字符串
print(r'hello\\n wo\trld')
结果
hello\\n wo\trld

zip 拉链函数,返回迭代器-节省内存,水桶效应

a = (1,2,3,4)
b = ('a','b','c')
c = ['111','222']
d = {'k1':'v1','k2':'v2'}
ret = zip(a,b,c,d)
print(ret)

for i in ret:
    print(i)
结果:
<zip object at 0x0000023ECB077108>
(1, 'a', '111', 'k1')
(2, 'b', '222', 'k2')

匿名函数
定义
匿名函数的内存地址 = lambda 参数1,参数2 : 返回值/返回值的表达式
调用
接收返回值 = 匿名函数的内存地址(参数)

def定义的函数: 都是有名字的,def后面写的就是函数名
def qqxing():
    print('qqxing')
func = qqxing
func2 = qqxing
print(qqxing.__name__)
print(func.__name__)    #内置属性,通过执行的函数名返回定义的函数名
print(func2.__name__)
结果
qqxing
qqxing
qqxing

事例2
def exe(func):
    func()
    print('执行%s函数了'%func.__name__)
def qqxing():
    print('qqxing')
def wahaha():
    print('wahaha')
exe(wahaha)
exe(qqxing)
结果
wahaha
执行wahaha函数了
qqxing
执行qqxing函数了


匿名函数没有名字,统一的名字是:<lambda>,别称: lambda表达式
定义一个很简单的函数,复杂的函数不要用lambda
def func(a,b):
    return a + b
ret = func(1,2)
print(ret)

fn = lambda a,b:a + b
ret = fn(5,6)
print(ret)
print(fn)
结果
3
11
<function <lambda> at 0x0000027766AD98C8>
使用场景: 配合着sorted,map,filter一起使用

事例2
qqxing = lambda n:n**2
print(qqxing.__name__)
ret = qqxing(8)
print(ret)
结果
<lambda>
64

事例3
f = lambda *args:sum(args)
ret = f(1,2,3)
print(ret)
执行结果
6

事例4
dic = {'k1':10,'k2':100,'k3':30}
m = max(dic,key=lambda k:dic[k])
print(m)
同等
def func(k):
    return dic[k]
m = max(dic,key=func)
print(m)
结果
k2

接收两个参数,返回较大值(不用max内置函数)
f1 = lambda a,b : max(a,b)
f2 = lambda a,b : a if a>b else b

sorted() 排序,根据key对应的函数的返回值的大小来排序的
由于必须要知道后面的值是谁,才能排出顺序,所以结果就是排序后的结果而不是可迭代的
按照字符串长度排序
执行流程: 把可迭代对象中的每一项拿出来, 作为参数传递给后面key函数,函数返回数字,根据数字进行排序

lst = ['关谷神奇','吕小布','诺兰','山口美惠子','']
def func(s):
    return len(s)
ret = sorted(lst,key=func)
print(ret)
同等
print(sorted(lst,key=lambda s:len(s)))
结果:
['', '诺兰', '吕小布', '关谷神奇', '山口美惠子']

事例2
lst = [
    {"name":"bob", "shengao":150, "tizhong":250},
    {"name":"jary", "shengao":158, "tizhong":150},
    {"name":"jack", "shengao":177, "tizhong":130},
    {"name":"pique", "shengao":165, "tizhong":130},
    {"name":"alice", "shengao":160, "tizhong":120},
    {"name":"athena", "shengao":183, "tizhong":190}
]
按照体重进行排序
按照身高进行排序
print(sorted(lst,key=lambda dic:dic['tizhong']))
print(sorted(lst,key=lambda dic:dic['shengao']))


事例3
l = [-3,1,2]
l.sort()
print(l)
def func(n):
    return abs(n)
l.sort(key = func)
print(l)
结果
[-3, 1, 2]
[1, 2, -3]

事例4
l = [1,-3,2]
new_l = sorted(l)   #在不改变原列表的情况下 生成一个新列表
print(l)
print(new_l)
def func(n):
    return abs(n)
ret = sorted(l,key = func)
print(ret)
结果
[1, -3, 2]
[-3, 1, 2]
[1, 2, -3]

事例5
按照每一个字典中商品的价格从高到低排列
l = [{'name':'电脑','price':1999},{'name':'鼠标','price':2000}]
def func(dic):
    return dic['price']
l.sort(key=func,reverse=True)
print(l)
同等
new_l = sorted(l,key = func,reverse= True)
print(new_l)
结果:
[{'name': '鼠标', 'price': 2000}, {'name': '电脑', 'price': 1999}]

filter 筛选

过滤掉名字结尾带刚字的人
把可迭代对象打开,把内部元素一个一个的传递给前面的函数,由这个函数决定此项是否保留
lst = ['旭日阳刚','金毛狮王','李刚','张杰']
f = filter(lambda name:not name.endswith(''),lst)
print(f)
print(list(f))
结果:
<filter object at 0x00000206FCB37208>   #可迭代对象
['金毛狮王', '张杰']

事例2
lst = [
    {"name":"bob", "shengao":150, "tizhong":250},
    {"name":"jary", "shengao":158, "tizhong":150},
    {"name":"jack", "shengao":177, "tizhong":130},
    {"name":"pique", "shengao":165, "tizhong":130},
    {"name":"alice", "shengao":160, "tizhong":120},
    {"name":"athena", "shengao":183, "tizhong":190}
]
ret = filter(lambda a:a['tizhong'] < 180,lst)
print(list(ret))
结果:
[{'name': 'jary', 'shengao': 158, 'tizhong': 150}, {'name': 'jack', 'shengao': 177, 'tizhong': 130}, {'name': 'pique', 'shengao': 165, 'tizhong': 130}, {'name': 'alice', 'shengao': 160, 'tizhong': 120}]

事例3
ret = filter(None,[1,2,3,0,False])  #只保留真的
print(ret)
for i in ret:
    print(i)
结果:
<filter object at 0x000002BD91BCEBA8>
1
2
3

事例4
def func(i):
    if i % 2 != 0:
        return True
l = [1, 4, 6, 7, 9, 12, 17]
for i in filter(func,l):  # 迭代l,每一个元素作为参数传给func,如果func的返回值为True,那么l中的这个元素就保留
    print(i)
结果:
1
7
9
17

事例5
def func(i):
    if type(i) is not dict:     #判断i类型不是dict的就返回True
        return True
同等
def func(i):
    return type(i) is not dict

l = ['sjkdhf',[1,2,3],{},()]    #去掉列表中的字典,用filter
ret = filter(func,l)
print(list(ret))
结果:
    ['sjkdhf', [1, 2, 3], ()]

# filter 就像 带着if条件的列表推导式
    l = ['sjkdhf',[1,2,3],{},()]
    print([i for i in l if type(i) is not dict])

map 映射函数
一个迭代器中的每一个元素都需要去做同一个操作并返回一个结果组成一个新列表的时候map来处理

lst = ['关谷神奇','吕小布','诺兰','山口美惠子','']
m = map(lambda s:'姓名:'+s,lst)
print(m)
for i in m:
    print(i)
结果:
<map object at 0x000001B76BAA7208>
姓名:关谷神奇
姓名:吕小布
姓名:诺兰
姓名:山口美惠子
姓名:易

事例2
列表中的每一个值的平方组成的新列表
lst = [1,5,78,12,16]
m = map(lambda i:i**2,lst)
print(list(m))
同等
print([i**2 for i in lst])
同等
lst = [1,5,78,12,16]
def func(num):
    return num**2
ret = map(func,lst)
print(list(ret))
结果:
[1, 25, 6084, 144, 256]

事例3
def func(i):
    return i*'*'
ret = map(func,[1,2,3])
print(ret)
for i in ret:
    print(i)
结果:
<map object at 0x0000024AEBB4ECC0>
*
**
***

eval() 有返回值,可以将字符串数据类型的python代码执行,通过拼接字符串的方式来执行不同的代码--简化代码
eval\exec这个函数,不能直接操作文件当中读进来的,从网络上传进来,用户输入的

eval('print(1+2+3+4)')  #返回10
ret = eval('1+2/3*4')
print(ret)              #有返回值
结果:
10
3.6666666666666665

事例2
code = input("请输入你要执行的代码:")
ret = eval(code)
print(ret)

事例3
把字符串类型的代码还原回字典, 列表, 元组
s = "{'name':'bob', 'age':18, 'isMan':False}"   #字符串
ret = eval(s)   #侧重的有返回值
print(ret)
print(type(ret))
结果:
{'name': 'bob', 'age': 18, 'isMan': False}
<class 'dict'>

事例4
with open('测试文件.txt','r',encoding='utf=8')as f:
    content=f.read()
    print(content,type(content))
    print(eval(content),type(eval(content)))
    print(eval(content)[0])
结果:
[{'id':1},{'name':'alex'}] <class 'str'>
[{'id': 1}, {'name': 'alex'}] <class 'list'>
{'id': 1}

将普通字符串'<'转换成<小于
def func(f):
    if eval('33 %s 20'%f):
        print('符合条件')
    else:
        print('不符合条件')
if '>':
    func('>')
if '<':
    func('<')

exec() 没有返回值,执行字符串类型的代码,不能太长,不能太乱

code = input("请输入你要执行的代码")
exec(code)  # 没有返回值. 想要返回值用eval
print(a)    # pycharm报错不一定准
结果:
请输入你要执行的代码a=3+4+9
16

事例2
exec('print(1+2+3+4)')  # 没有返回值,想要返回值用eval
ret = exec('1+2/3*4')
print(ret)              #没有返回值None
exec('for i in range(3):print(i)')
执行结果
10
None
0
1
2

compile编译  
把要执行的代码先预编译,能够节省时间工具,通过exec和eval可以执行我们的代码
参数说明:
resource 要执行的代码,动态代码⽚片段
文件名,代码存放的文件名,当传入了第一个参数的时候,这个参数给空就可以了
模式,取值有3个
    exec: 一般放一些流程语句句的时候
    eval: resource只存放一个求值表达式.
    single: resource存放的代码有交互的时候,mode应为single

先编译 python -编译-> 字节码(bytes) -解释-> 机器码 0101010100101
先整体编译
code1 = 'for i in range(0,3): print (i)'   #这是一个字符串代码

事例1
流程语句使用exec
compile1 = compile(code1,'','exec')     #预编译 python-> 字节码
exec (compile1)  #解释
exec (compile1)
exec(code1)     #编译+解释
结果:
0
1
2
0
1
2
0
1
2

事例2
简单求值表达式用eval
code2 = '1 + 2 + 3 + 4'
compile2 = compile(code2,'','eval')
print(eval(compile2))
结果:
10

事例3
交互语句用single
code3 = 'name = input("please input your name:")'
compile3 = compile(code3,'','single')
exec(compile3)
print(name)
结果:
please input your name:linux
linux