复习主要内容有:高阶函数、递归、文件操作、random、json、os、装饰器、可迭代对象、迭代器、生成器
函数部分
此时此刻我的内心是想着怎么放松一下,哈哈哈,年轻人说那么多废话,干他就完了,再不干你就要慢慢被社会淘汰了,一步一步不断提升,稳赢,来吧gogogo 》》》
来吧,给自己上一课
First:高阶函数
其实高阶函数也为内置函数
1:一个函数可以接受另一个函数作为参数
2:变量可以指向函数,abs=10,abs(-10)
3:函数名可作为变量
4:传入函数
编写高阶函数就是为了:让函数的参数能够接收别的函数
def add(x,y,f):
return f(x)+f(y)
add(-10,10,abs)
second:迭代
判断是否为可迭代对象:
from collections import Iterable
print(isinstance('abs',Iterable))
任何可迭代对象都可以用为for循环
如果一个对象具有__iter__方法,则称为可迭代对象
可迭代对象执行__iter__方法返回的结果称为迭代器
可迭代对象只有__iter__方法,而迭代器则有__iter__、__next__两个方法。
def while_iterator(iterable_obj):
iterator_obj = iter(iterable_obj) # iter函数返回迭代器iterator_obj
while 1:
try:
print(next(iterator_obj), end=' ') # next方法返回每个元素
except StopIteration:
return
while_iterator('123') # 1 2 3
while_iterator({'a', 'b', 'c'}) # b c a
Third:生成器
函数体内包含有yield关键字,那么该函数被称为生成器函数,而该函数执行的结果(返回值generator_obj)为生成器
一种特殊的迭代器——生成器。
def generator_func():
print('first')
yield 1
print('second')
yield 2
print('third')
yield 3
generator_obj = generator_func()
print(generator_obj.__next__())
print(''.center(20, '*'))
for i in generator_obj:
print(i)
'''
first
1
********************
second
2
third
3
'''
生成器表达式VS列表解析式
l = [i for i in range(10)]
g = (i for i in range(10))
print('l: ', l) # l: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print('g: ', g) # g: <generator object <genexpr> at 0x00DE5AB0>
生成器表达式返回的是生成器对象。而列表解析式返回的是列表
import time
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
func(*args, **kwargs)
print('%s running time: %s' % (func.__name__, time.time() - start))
return wrapper
@timer
def gen():
i = (i for i in range(10000000))
print(i)
@timer
def li():
[i for i in range(10000000)]
gen()
li()
'''
<generator object gen.<locals>.<genexpr> at 0x00A88CF0>
gen running time: 0.0
li running time: 0.7966420650482178
'''
从创建时间来说,生成器表达式完成的时间太快了(其实就返回了一个生成器),我们的timer时间装饰器没有测出时间,而列表解析则非常耗时,而这只是千万级,如果是亿级的列表,一般的电脑则会报MemoryError的错误
def func():
print('first')
result1 = yield 1
print(result1, 'second')
result2 = yield 2
print(result2, 'third')
yield 3
gen = func() # 首先拿到一个生成器对象
print(gen.send(None)) # 1
print(gen.send('a')) # 2
print(gen.send('b')) # 3
print(gen.send('c')) # StopIteration
"""
first
1
a second
2
b third
3
StopIteration
"""
生成器有个send方法可以在外部和生成器内部进行通信,比如从外部传值给生成器内部,这在一些特定情况下比较有用
Fourth:装饰器
1:动态增加功能的方式
2:对扩展开放
3:对修改封闭(开放封闭原则)
导入:import functools
分类:
1:有参装饰器 2:无参装饰器 3:多装饰器
方法:
通过 函数参数.name():可以拿到函数对象名
注意:装饰器,语法糖,在Python程序中添加某种语法目标,添加新功能,关键点:@符号
def timer(func):
pass
@timer
def index(x):
pass
语法糖作用:
index=timer(index)
实现一个统计函数执行时间的装饰器
import time
import random
def timmer(func):
def wrapper(*args, **kwargs):
start = time.time()
res = func(*args, **kwargs)
print('{} running time {}'.format(func__name__,time.time() - start)
return res
return wrapper
@timmer
def foo():
time.sleep(random.random())
foo()
Fifth:random
import random
#取随机值的
#取0-1的随机小数
print(random.random())
#取1-3之间的整数,[1,3]
print(random.randint(1,3))
#取整数,顾头不顾尾[1,3)
print(random.randrange(1,3))
#从指定字符串,数字或者列表等数中取值,指定的选值需要用列表的形式保存,相当于从列表中取一个值
print(random.choice([1,'shimmer',[4,5]]))
#列表中取多元素一起组合,可以规定几个数
print(random.sample([1,5,6,8,[4,7],'alex'],2))
# 取小数,即不顾头也不顾尾(1,3),浮点数
print(random.uniform(1,3))
print(random.uniform(2,10))
print(random.uniform(3,11))
# 打乱顺序
item=[1,2,3,4,5]
random.shuffle(item)#打乱item顺序,需要先打乱才能输出
print(item)
#应用: 随机验证码
# 大写字母:chr(random.randint(65,90))
#小写字母:chr(random.randint(113,122)
i=0
res=''
for i in range(6):
#大写英文字母
s1 =chr(random.randint(65,90))
# 小写英文字母
s2 =chr(random.randint(113,122))
# 数字
y=str(random.randint(0,9))
res+=random.choice([s1,s2,y])
i+=1
print(res)
使用相关模块生成6为的验证码,验证码内容包括随机数字、随机小写字符、随机大写字符
import random
import string
# 法1
def code(n=6):
end = ''
for i in range(n):
num = str(random.randint(0,9))
alpha_up = chr(random.randint(65,90))
alpha_low = chr(random.randint(97,122))
aim = random.choice([num,alpha_up,alpha_low])
end += aim
return end
print(code(6)) # 传几位就生成几位验证码
# 法2 这个有点问题,这个会出现全部大写或者全部小写的情况
def foo(n):
return ''.join(random.sample(string.digits + string.ascii_lowercase + string.ascii_uppercase, n))
print(foo(6))
sixth:os
import os
# 获取当前工作目录,相当于Linux的pwd
print(os.getcwd())
# #改变当前脚本工作目录,相当于虚拟机里的cd
print(os.chdir('E:\PY\路飞学城\第二模块'))
# # 返回当前目录.
# print(os.curdir)
# #生成多层递归目录
# os.makedirs('dirname1/dirname2/dirname3')
#若目录为空则删除,并递归到上一级目录,如若也为空则删除,以此类推,要删除的文件必须是空的,否则报错
# os.removedirs("dirname1/dirname2/dirname3")
# 生成单级目录
print(os.mkdir('复习'))
#删除单级目录,删除后但会none,删除成功
# print(os.rmdir('dirname1'))
# 列出所指定目录下的所有文件和子目录,包括隐藏文件,并以列表的方式打印
# print(os.listdir('dirname1'))
# 删除一个文件,删除时也必须为空,不为空或者下层还有其他文件也会报错
# os.remove('dirname1')
# 重命名文件、目录
os.rename('网站访问日志分析运行文件.py','员工信息查询运行文件.py')
# 获取文件目录信息
# print(os.stat('E:\PY\路飞学城\第二模块'))
# 获取文件大小
# print(os.path.getsize("dirname"))
# 规定:key与value必须都是字符串
#os.environ获取系统的环境变量
# os.environ['环境变量名称']='环境变量值' #其中key和value均为string类型
# os.environ 是一个字典,是环境变量的字典,
# 系统不一样环境变量大小写也会有影响,Windows下全部返回大写,OS下返回小写,Linux也是小写
# os.environ["aaaaaaaaa"]='11111111'
# os.environ["HHHHHHHH"]='22222'
# os.environ["hhhhhhh"]='22222'
# print(os.environ)
#
# print(os.system("ls /"))
#返回path规范化的绝对路径
# print(os.path.abspath('dirname'))
#将path分隔成目录和文件名二元组返回
# print(os.path.split('dirname3'))
# 返回path的目录。其实就是os.path.split(path)的第一个元素
# print(os.path.dirname('E:\PY\路飞学城\第二模块\dirname'))
# 返回path最后的文件名,如果path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
# print(os.path.basename('E:\PY\路飞学城\第二模块\dirname'))
# 返回空值,\或/后需要空一格
# print(os.path.basename('E:\PY\路飞学城\第二模块\dirname\ '))
#判断是否存在
# print(os.path.exists('dirname'))
# print(os.path.exists('dirname5'))
#判断是否是绝对路径
# print(os.path.isabs('dirname'))
#判断path是否是一个已存在的文件
# print(os.path.isfile('dirname'))
# print(os.path.isfile('shutil模块.py'))
# 判断是否是一个目录
# print(os.path.isdir('dirname'))
#将多个路径组合后返回,第一个绝对路径之前的参数将被忽略、
# os.path.join()函数:连接两个或更多的路径名组件
#
# 1.如果各组件名首字母不包含’/’,则函数会自动加上
#
# 2.如果有一个组件是一个绝对路径,则在它之前的所有组件均会被舍弃
#
# 3.如果最后一个组件为空,则生成的路径以一个’/’分隔符结尾
# print(os.path.join('E:','PY,路飞学城,第二模块,dirname,dirname2'))
#
# Path1='home'
# Path2='develop'
# Path3='code'
# Path10=Path1+Path2+Path3
# print(Path10)
# #路径连接用\分开
# Path20=os.path.join(Path1,Path2,Path3)
# print(Path20)
如何获取当前脚本的绝对路径
import os
print(os.path.abspath(__file__))
如何获取当前脚本的父级目录
import os
print(os.path.abspath(__file__))
print(os.path.dirname(os.path.abspath(__file__)))
seventh:json
导入:import json
eval()不解析null类型,json可以.null会被解析成none
注意:json必须使用双引号
JSON 值可以是:
数字(整数或浮点数)
字符串(在双引号中)
逻辑值(true 或 false)
数组(在中括号中)
对象(在大括号中)
null
规则:
数据在名称/值对中
数据由逗号分隔
大括号 {} 保存对象
中括号 [] 保存数组,数组可以包含多个对象
名称/值对:key:value的格式
JSON 数字
{ "age":18 }
JSON 对象
{ "name":"shimmer" ,"age":18 }
JSON 布尔值
{ "flag":true }
JSON null
{ "status":null }
JSON 数组
{[
"name":"shimmer",
"age":18,
"sex":"female"
]}
有d = {‘a’: 1, ‘b’: 2, ‘c’: 3},请将它序列化到文件
import json
d = {'a': 1, 'b': 2, 'c': 3}
with open('a.txt', 'w', encoding='utf-8') as f:
json.dump(d, f)
eighth:文件操作
打开文件常用方式:open (“文件名”,“操作方式”,endonding="utf-8")
操作方式:
有时会处理一些其他类型文件(二进制文件),如音、视频文件,那么就应该在模式参数中增加b模式,如rb模式读取二进制文件
常用方法:
w模式和write
f1 = open('t1.txt', mode='w')
f1.write('hello\n')
f1.write('world\n')
f1.close()
r模式和read系列
f2 = open('t1.txt', mode='r')
content=f2.read()#读取全部
print(content)
content1=f2.read(5)#指定读取字节数
f2.readline()#按行读取,但是第一行读不到,没两行之间空一行读取,类似于多行的有一行的间隔读取
f2.readlines()#读取所有行,并以列表的形式输出
seek/tell:随机读取文件方法
seek(数字):指定光标位置
tell():输出光标当前所在位置
f9 = open('T1.txt', 'r',encoding="utf-8")
print(f9.tell())
f9.seek(2)
print(f9.tell())
content=f9.read()
print(content)
print(f9.tell())
f9.close()
"""
0
2
jfzxkf
8
"""
文件操作,使用Python将图片新建一个副本,比如有a.jpg,使用Python得到副本b.jpg
with open('a.jpg', 'rb') as rf:
with open('b.jpg', 'wb') as wf:
wf.write(rf.read())
ninth:递归
递归:一个函数在内部调用自己本身
递归调用:程序在调用一个函数的过程中,直接或者间接调用了该函数本身
计算1+2+3+…+x的和
def mySum(x):
if x == 1: # 递归结束条件
return 1
return mySum(x - 1) + x
print(mySum(5)) # 15
'''
mySum(5)
mySum(4) + 5 15
mySum(3) + 4 10
mySum(2) + 3 6
mySum(1) + 2 3
1
'''
上面的例子还可以有另一种更加优美的写法——三元表达式:
def mySum(x):
return 1 if x == 1 else mySum(x - 1) + x
print(mySum(5))
递归做个总结:
递归必须有明确的结束条件,避免陷入死递归。
递归使代码更加整洁、优美。
递归调用过程晦涩难懂。
递归非常的占用内存空间,因为每层递归都保留当前的层的状态信息,也会造成递归的时间成本更高,效率低下。
Python标准解释器没有针对为递归对优化,任何递归函数都存在溢出的问题
递归统计指定目录下的文件个数:
import os
def foo(path):
if os.path.isdir(path):
total = 0
for line in os.listdir(path):
tmp_path = os.path.join(path, line)
if os.path.isdir(tmp_path):
total += foo(tmp_path)
else:
total += 1
return total
else:
exit('给定的路径不是目录')
if __name__ == '__main__':
print(foo(r"D:\tmp"))
内置函数
目录
让人又爱又恨的lambda
映射函数:map
拉链函数:zip
过滤函数:filter
累积函数:reduce
其他内置函数
返回Python目录
1:lambda:匿名函数
用法:用lambda创建函数,一般只是把函数赋值给变量,通过这个变量加括号执行lambda并获取结果,并不是得语句将函数赋值给变量。匿名是说在内存空间中只有函数内存地址没有函数名。
语法:lambda arg1,arg2,......:expression
声明函数 参数 表达式
1:支持多个函数 2:支持if/else语句
3:如果表达式为判别式,返回True或False
4:多层赋值函数,在多层嵌套函数里,先赋值给最外层。lambda也是一样的
5:lambda执行的功能有限
如果需要用函数实现简单的功能,lambda表达式就可以替代def语句形式:
def foo(x):
return x ** 2
print(foo(2)) # 4
l = lambda x: x ** 2
print(l(3)) # 9
print((lambda x: x ** 2)(3)) # 9
l = (lambda x: (lambda y: x < y))
print(l) # <function <lambda> at 0x00FA4B28>
l1 = l(10) # 基准值 x:10
print(l1) # <function <lambda>.<locals>.<lambda> at 0x00C26738>
print(l1(5)) # False
print(l1(20)) # True
优化:
print((lambda x: (lambda y: x < y))(10)(5)) # False
print((lambda x: (lambda y: x < y))(10)(20)) # True
** 2:map:映射函数**
语法:map(func,*iterables)
# func: 可执行的函数
# iterables:迭代器,可迭代的序列
导入:from collections import Iterable
,在Python3.9后就不需要导入了
def f2(x):
return x ** 2
map_obj = map(f2, range(1, 5))
print(map_obj) # <map object at 0x000001FBA0311668>
print(isinstance(map_obj, Iterable)) # True
print(list(map_obj)) # [1, 4, 9, 16]
1:map将第二个参数的值交给第一个参数去计算,并将结果收集返回一个map对象(其本质是个可迭代对象),数据需要显式的通过list强转或for循环取值
2:map也支持多个序列同时执行函数:print(list(map(lambda x, y: x ** y, [2, 3, 4], [3, 2, 2]))) # [8, 9, 16]
上例,map函数将两个列表元素根据索引——映射为key:value的格式传递给lambda的x,y参数,计算后返回结果。
3:map函数将多个序列内的元素以映射的方式交给函数执行,且无法映射的将会被丢弃
#用map来处理列表,把列表中所有人都变成xx_666,如张开_666,
#name = ["张开", "李开", "王开", "赵开"]
name = ["张开", "李开", "王开", "赵开"]
print(list(map(lambda x: x + '_666', name)))
"""
使用map来处理列表,将列表中每个人的名字都变成以xx_666,如张开_666
tmp_list = [{'name': '张开'}, {'name': '李开'}, {'name': '王开'}, {'name': '赵开'}]
"""
tmp_list = [{'name': '张开'}, {'name': '李开'}, {'name': '王开'}, {'name': '赵开'}]
print(list(map(lambda x: x['name'] + '_666', tmp_list)))
3:zip:拉链函数
zip函数用于将可迭代对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象。
语法:
zip(iterables,iterables2,...iterablesn)
# iterables:可迭代对象
# 显示转化为列表的形式
l1=[1,2,3]
l2=["shimmer","winter","winner"]
zip_obj=zip(l1,l2)
print(list(zip_obj))
# 显示转化为字典的形式
l3=["大商股份","登记股份","贷款股份"]
tmp_list=[]
for l in (l1,l2):
tmp_list.append(dict(zip(l3,l)))
print(tmp_list)
1:如果各个可迭代对象的元素个数不一致,则返回的对象长度与最短的可迭代对象相同
2:zip将两个可迭代对象中的元素按照索引进行映射为元组,如果显式转换为列表,结果就是列表套元组的形式;如果显式转换为字典,则结果就是字典。
3:如果显式转化为列表,结果就是列表套元祖的形式
title = ["股票名称", "股票代码", "最新价"]
value1 = ["顺威股份", 2676, 3.69]
value2 = ["嘉泽新能", 601619, 4.91]
value3 = ["东方园林", 2310, 5.57]
print(list(zip(title, value1)))
print(list(zip(title, value1, value2)))
print(list(zip(title, value1, value2, value3)))
"""
[('股票名称', '顺威股份'), ('股票代码', 2676), ('最新价', 3.69)]
[('股票名称', '顺威股份', '嘉泽新能'), ('股票代码', 2676, 601619), ('最新价', 3.69, 4.91)]
[('股票名称', '顺威股份', '嘉泽新能', '东方园林'), ('股票代码', 2676, 601619, 2310), ('最新价', 3.69, 4.91, 5.57)]
"""
4:filter:过滤函数
filter函数根据条件过滤序列,将符合条件的元素返回。
语法:
filter(func, *iterables)
func: 可执行的函数
iterables:可迭代对象,可迭代的序列
用filter来处理,得到股票价格大于20的股票名字
shares={
‘IBM’:36.6,
‘Lenovo’:23.2,
‘oldboy’:21.2,
‘ocean’:10.2,
}
shares={
'IBM':36.6,
'Lenovo':23.2,
'oldboy':21.2,
'ocean':10.2,
}
m=filter(lambda key:shares[key]> 20,shares) #匿名函数的用法,题目一有详细注释
#filter函数的用法和map()函数类似,但filter返还的是key值。参考题目一
print(list(m))
---->['IBM', 'Lenovo', 'oldboy']
用filter过滤出,单价大于100的股票有哪些
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}
]
m=filter(lambda k:k['price'] > 100 ,portfolio)
print(list(m))
----->[{'name': 'AAPL', 'shares': 50, 'price': 543.22}, {'name': 'ACME', 'shares': 75, 'price': 115.65}]
1:filter函数中的第一个参数为None的话,则将为真的元素返回,如果返回的是不可调用对象的话,会报错。
2:filter函数根据条件过滤序列,将符合条件元素返回
3:filter也需要强装换才能返回数据
4:元素键名相同时:filter(lambda x:x[键名]条件,字典名)
5:键名不同时:filter(lambda k:字典名[k]条件,字典名)
5:reduce:累积函数
注意:Python3中 reduce() 已经被移到 functools 模块里,如果我们要使用,需要引入 functools 模块来调用 reduce() 函数:需要先导入:from functools import reduce
reduce函数语法如下:
reduce(func, sequence, initializer)
func: function
sequence: 序列
initializer: 初始值,可选参数
1:如果序列为空,则将initializer值返回。
6:其他内置函数:
1:max/min
print(max(['b', 'c', 'e'])) # e
print(min(['b', 'c', 'e'])) # b
print(max([1, 'b', 3, 5, 'd'])) # TypeError: '>' not supported between instances of 'str' and 'int'
max/min返回序列的最大值和最小值,但要求是序列中的数据类型必须一致,不然无法比较
2:range
from collections import Iterable
res = range(3)
print(res) # range(0, 3)
print(isinstance(res, Iterable)) # True
print(list(res)) # [0, 1, 2]
在Python3中,range返回的是一个可迭代对象,需要显式的调用其中的元素。
3:chr/ord
print(chr(97)) # a
print(ord('a')) # 97
print(chr(1000)) # Ϩ
print(chr(1114111)) #
print(chr(1114112)) # ValueError: chr() arg not in range(0x110000)
一般,我们通常使用chr和ord函数查看range(256)范围内整数对应的字符。但chr函数也能返回基于Unicode16位编码方式的整数对应的字符,它的范围是0~1114111,超过此范围就报错。
常用chr转换对应数字为对应英文字符,这个还是比较常用的:小写a-z为数字:97-122,大写A-Z为数字:65-90
4:进制转换
bin函数返回十进制的二进制表示;oct函数返回十进制的八进制表示;hex函数返回十进制的二进制。
print("10-->2", bin(20)) # 0b10100
print("10-->8", oct(20)) # 0o24
print("10-->16", hex(20)) # 0x14
如果八进制转十六进制,或者十六进制转二进制该怎么办
print('2-->8: ', oct(int('0b1010', 2))) # 2-10-8
print('2-->10:', int('0b1010', 2)) # 2-10
print('2-->16:', hex(int('0b1010', 2))) # 2-10-16
print('8-->2:', bin(int('0o12', 8))) # 8-10-2
print('8-->10:', int('0o12', 8)) # 8-10
print('8-->16:', hex(int('0o12', 8))) # 8-10-16
print('10-->2', bin(10)) # 10-2
print('10-->8', oct(10)) # 10-2
print('10-->16', hex(10)) # 10-16
print('16-->2:', bin(int('0xa', 16))) # 16-10-2
print('16-->8:', oct(int('0xa', 16))) # 16-10-8
print('16-->10:', int('0xa', 16)) # 16-10
"""
2-->8: 0o12
2-->10: 10
2-->16: 0xa
8-->2: 0b1010
8-->10: 10
8-->16: 0xa
10-->2 0b1010
10-->8 0o12
10-->16 0xa
16-->2: 0b1010
16-->8: 0o12
16-->10: 10
"""
10进制转别的进制直接使用对应的函数。而其他的进制转换都要先将本进制转为10进制,再通过各自进制的方法转换这个10进制数字就可以了。而需要注意的是int函数在将别的进制转换为10进制时,第一个参数要以字符串的形式传参。
5:dir
def foo():
pass
print(dir())
print(dir(foo))
"""
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'foo']
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
"""
当dir函数不指定参数的时候,返回当前作用域的变量及属性,而当指定参数的时候,则返回指定参数的属性。
6:globals/locals
def foo():
x, y = 2, 3
print(locals())
print(globals())
foo()
print(locals())
print(globals())
"""
{'y': 3, 'x': 2}
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000027355A6B518>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/tmp/test.py', '__cached__': None, 'foo': <function foo at 0x0000027355A11EA0>}
"""
locals函数一般用于局部作用域内,以字典的形式返回局部变量。而globals无论在局部还是全局,都以字典的形式返回当前位置的全局变量。如果locals用在全局,则跟globals返回的内容一致。
7:repr/str
print(repr('abc')) # 'abc'
print(str('abc')) # abc
repr函数将对象返回字符串的形式,类似str函数,但是repr返回的对象更友好与解释器(更加规范,返回的更多信息,倾向于解释器),而str配合print返回的结果对用户更友好(提高用户的可读性,倾向于用户)。
8:sorted/list.sort
sorted函数将可迭代对象内的元素以升序的形式排序,并将排序结果以一个新列表的形式返回,相当于完全拷贝了一份原列表,然后对副本进行排序。
而sort只是列表自带的排序方法,并且是原地排序,即在原列表上进行排序。
这两个排序各有优势,sorted比list.sort更为强大,适用范围更广泛。在实际应用中,如果需要保留原列表,则采用sorted函数排序,否则可以选择list.sort方法,因为list.sort无需复制原列表,在效率和内存占用上更有优势。
"""
将下面的列表内的元素以age升序排序:
tmp_list = [
{'name': '张开', 'age': 18}, {'name': '李开', 'age': 8},
{'name': '王开', 'age': 32}, {'name': '赵开', 'age': 25}
]
"""
tmp_list = [
{'name': '张开', 'age': 18}, {'name': '李开', 'age': 8},
{'name': '王开', 'age': 32}, {'name': '赵开', 'age': 25}
]
#1:tmp_list.sort(key=lambda x: x['age'], reverse=False)#这条语句跟下面那条语句都可以得到题目想要的结果
tmp_list.sort(key=lambda x:x.get('age'),reverse=False)
print(tmp_list)
l1 = [2, 3, 1, 5, 4, 9]
print(id(l1)) # 2186440903304
s1 = sorted(l1) # 默认是升序排序
s2 = sorted(l1, reverse=True) # reverse为True时,降序排序
print(s1, id(s1)) # [1, 2, 3, 4, 5, 9] 2186440801672
print(s2, id(s2)) # [9, 5, 4, 3, 2, 1] 2186439007176
l2 = [4, 8, 3, 5, 7, 6]
print(id(l2)) # 2046115172296
l2.sort()
print(l2, id(l2)) # [3, 4, 5, 6, 7, 8] 2046115172296
l2.sort(reverse=True) # reverse为True时,降序排序
print(l2, id(l2)) # [8, 7, 6, 5, 4, 3] 2046115172296
9:round
round函数默认返回浮点数的四舍五入后的整数值,而指定ndigits参数,则返回四舍五入后的浮点类型的数值,小数位的位数取决于ndigits的参数值。
from math import pi
print(pi) # 3.141592653589793
print(round(pi)) # 3
print(round(pi, 3)) # 3.142
记得有一次老师出题,我看了前半部分没看后半部分,老师要求不保留小数,我看到前面给出来3.14,然后我就给他输出来3.14,结果后半部分说请给我输出无小数位的数,不看题的我把自己给整笑了,都不知道自己怎么看的题,就是下面那题
有派3.14 如何去掉小数位? 请用内置函数实现,注意不能使用切片
print(round(3.14))
10:enumerate
for number, value in enumerate(range(6)): # # 传递一个可迭代对象,start参数默认为0
print(number, "\t",value)
"""
number value
0 0
1 1
2 2
3 3
4 4
5 5
"""
for number, value in enumerate(range(6), start=10): # # 传递一个可迭代对象,start参数默认为0
print(number, "\t",value)
"""
number value
1 0
2 1
3 2
4 3
5 4
6 5
"""
enumerate(iterable, start=0)函数接收两个参数,iterable参数接收一个可迭代对象,而start参数则是指定在循环中,为每个元素设置序号的起始位置。start参数(默认为0)可以指定。一般较多的用在for循环中。
一般返回的是索引跟值