文章目录
- 1. 常用操作
-
- 1.1. 数字相关操作
- 1.2. 调用Tcl
- 1.3. 时间
- 1.4. 进制转换
- 1.5. 格式化字符
- 1.6. 排序
- 1.7. 处理命令行参数
- 1.8. 系统命令
- 1.9. json操作
- 1.10. 处理文件
- 1.11. 分析程序性能cProfile
- 1.12. 修改python搜索模块的路径集
- 1.13. 标准输入、标准输出、标准错误
- 1.14. 使用pip安装模块
- 1.15. python文件的打包/破解/加密
- 1.16. 生成文件md5码
- 1.17. 在类内部获取类名, 在函数内部获取函数名
- 1.18. 几个函数
- 1.19. 代码换行
- 1.20. Unicode编码转换
- 1.21. 三目运算
- 1.22. 获取terminal窗口大小
- 2. 正则表达式
- 3. 常量、变量、运算符、表达式
- 4. 控制流
- 5. 函数
- 模块
- 数据类型
- 面向对象
- 面向对象高级编程
- 错误和异常
1. 常用操作
1.1. 数字相关操作
1.1.1. 绝对值
>>> abs(-5.0)
5.0
1.1.2. 数字取整
1.1.2.1. 只取整数部分int()
int(), 直接截去小数部分,剩下整数部分, 返回int型数;
>>> int(5.0) # 5
>>> int(5.1) # 5
>>> int(5.9) # 5
>>> int(6.0) # 6
>>>
>>> int(-5.0) # -5
>>> int(-5.1) # -5
>>> int(-5.9) # -5
>>> int(-6.0) # -6
1.1.2.2. 向下取整math.floor()
math.floor() 向下取整,返回int型数;
>>> math.floor(5.0) # 5
>>> math.floor(5.1) # 5
>>> math.floor(5.9) # 5
>>> math.floor(6.0) # 6
>>>
>>> math.floor(-5.0) # -5,小于等于-5.0 的最大整数是-5;
>>> math.floor(-5.1) # -6,小于等于-5.1 的最大整数是-6;
>>> math.floor(-5.9) # -6,小于等于-5.9 的最大整数是-6;
>>> math.floor(-6.0) # -6,小于等于-6.0 的最大整数是-6;
1.1.2.3. 向上取整 math.ceil()
math.ceil() 向上取整,返回int型数;
>>> math.ceil(5.0) # 5
>>> math.ceil(5.1) # 6
>>> math.ceil(5.9) # 6
>>> math.ceil(6.0) # 6
>>>
>>> math.ceil(-5.0) # -5,大于等于-5.0 的最小整数是-5;
>>> math.ceil(-5.1) # -5,大于等于-5.1 的最大整数是-5;
>>> math.ceil(-5.9) # -5,大于等于-5.9 的最大整数是-5;
>>> math.ceil(-6.0) # -6,大于等于-6.0 的最大整数是-6;
1.1.2.4. 四舍五入round()
round(number[, ndigits]) 四舍五入,如果两边整数一样远,刚返回偶数一边;
参数ndigits表示小数位的数目;如果ndigits=0,返回int型数,如果ndigits>=1, 返回float型数;
>>> round(-2.5) # -2
>>> round(-1.5) # -2
>>> round(-0.5) # 0
>>> round( 0.5) # 0
>>> round( 1.5) # 2
>>> round( 2.5) # 2
>>> round(1.05, 1) # 1.1 本应该靠偶数一边是1.2, 但由于内部存储原因,返回1.1;
#1.05
# + 0.0000_0000_0000_0010
# -----------------------
# = 1.0500_0000_0000_0012
# 所以1.05更靠近1.1 这边;
>>> round(1.15, 1) # 1.1 本应该靠偶数一边是1.2, 但由于内部存储原因,返回1.1;
#1.15
# + 0.0000_0000_0000_0002
# -----------------------
# = 1.1500_0000_0000_0001
# 所以1.05更靠近1.1 这边;
>>> round(1.25, 1) # 1.2
>>> round(1.35, 1) # 1.4
>>> round(1.45, 1) # 1.4
>>> round(1.55, 1) # 1.6
>>> round(1.65, 1) # 1.6
>>> round(2.675, 2) # 2.67, 本应该靠偶数一边是2.68, 但由于内部存储原因,返回2.67;
在python2.7的doc中,round()的最后写着,"Values are rounded to the closest multiple of 10 to the power minus ndigits; if two multiples are equally close, rounding is done away from 0."保留值将保留到离上一位更近的一端(四舍六入),如果距离两端一样远,则保留到离0远的一边。所以round(0.5)会近似到1,而round(-0.5)会近似到-1。
但是到了python3.5的doc中,文档变成了"values are rounded to the closest multiple of 10 to the power minus ndigits; if two multiples are equally close, rounding is done toward the even choice."如果距离两边一样远,会保留到偶数的一边。比如round(0.5)和round(-0.5)都会保留到0,而round(1.5)会保留到2。
round(2.675, 2) 的结果,不论我们从python2还是3来看,结果都应该是2.68的,结果它偏偏是2.67,为什么?这跟浮点数的精度有关。我们知道在机器中浮点数不一定能精确表达,因为换算成一串1和0后可能是无限位数的,机器已经做出了截断处理。那么在机器中保存的2.675这个数字就比实际数字要小那么一点点。这一点点就导致了它离2.67要更近一点点,所以保留两位小数时就近似到了2.67。
1.1.3. 乘方、开方
pow(x, y) # 求x的y次方;
>>> pow(3, 2) # 9,求平方,返回int型数;
>>> pow(3, 1/2) # 1.7320508075688772, 1/2次方即开方运算;
>>> pow(4, 1/2) # 2.0, 平方根返回的是float型数;
math.pow(),与pow()类似
>>> math.pow(3, 2) # 9.0, 返回的是float型数
对于求平方根,除了可以使用math.pow(x, 1/2)外,还有专门的平方根函数math.sqrt(x)
>>> math.sqrt(2) # 1.4142135623730951,求平方根
>>> math.sqrt(4) # 2.0, 平方根返回的是float型数;
1.1.4. 三角函数、对数
三角函数
>>> math.pi # 3.1415_9265_3589_793, 使用math.pi可以调用π;
>>> math.sin(math.pi / 6) # 0.4999_9999_9999_9999_4,得到的并不是0.5;
>>> math.cos(math.pi / 3) # 0.5000_0000_0000_0001,得到的并不是0.5;
>>> math.tan(math.pi / 4) # 0.9999_9999_9999_9999,得到的并不是1.0;
对数,math.log(A, B=e) 以B为底,A的对数,默认以e为底;
>>> math.e # 2.7182_8182_8459_045,自然常数e;
>>> math.log(100, 10) # 2.0,返回的是float型数;
>>> math.log(math.e) # 1.0,
1.1.5. 随机数
1.1.5.1. 随机整数
randint(a, b),[a, b]之间的整数,包含b;
>>> import random
>>> random.randint(10, 20) # 16,返回[10, 20]之间的随机整数;算个bug吧
>>> random.randint(20, 10) # 报错ValueError,参数对顺序有要求;
>>> random.randint(10, 10) # 10,上下限相同,返回这个数;
randrange(start, stop=None, step=1, _int=<class ‘int’>), 不包含stop
>>> random.randrange(10, 20, 2) # 返回[10, 20)之间的偶数,不包括stop
1.1.5.2. 随机浮点数
uniform(a, b), [a, b]之间的浮点数,包含b;
>>> import random
>>> random.uniform(10, 20) # 12.132xxxxx,返回[10, 20]之间的随机浮点数;
>>> random.uniform(20, 10) # 10.414xxxxx,uniform(),两个参数不关心顺序;
>>> random.uniform(10, 10) # 10.0,上下限相同,返回这个数;
random.random(), [0, 1)之间的浮点数,不包含1;不需要参数
>>> random.random()
0.1862385***
1.1.5.3. 在待选中随机选择
语法:random.choice(seq)
参数:seq可以是列表、元组、字符串
返回:返回一个元素
>>> import random
>>> random.choice([1, 3, 5]) # 从list中随机选择一个
3
>>> random.choice('abc!@#') # 从str中随机选择一个
#
语法:random.sample(seq, n)
参数:seq,列表、元组、字符串;n,数目;
返回:返回一个列表
>>> import random
>>> random.sample([1, 3, 5, 7, 9], 3) # 从list中随机选择三个
[5, 1, 3]
>>> random.sample('abc!@#') # 从str中随机选择三个
['a', '#', 'b']
1.1.5.4. 打乱序列
语法:random.shuffle(x, random=None)
参数:x,一个list;random,??
返回:返回None,传入的lst会被改变
>>> import random
>>> L0 = [1, 2, 3, 4, 5]
>>> random.shuffle(L0) # 将L0洗牌, 该语句返回None
>>> L0
[4, 5, 3, 1, 2]
1.1.6. 平均值/方差/标准差
需要第三方模块 numpy
import numpy as np
f_mean = np.mean(_list) # 平均值
f_var = np.var(_list) # 方差
f_std = np.std(_list, ddof=1) # 标准差
1.2. 调用Tcl
>>> import tkinter
>>> interp tkinter.Tcl()
1.2.1. 通过eval调用tcl命令,返回值为str
>>> # 调用tcl语句
>>> interp.eval('source xx.tcl')
>>>
>>> # 调用array names返回str,split后赋值给list
>>> list_a0_names = interp.eval('array names a0').split()
>>>
>>> # 调用llength 返回str,int后赋值给整形变量
>>> i_length = int(interp.eval('llength $list0'))
>>>
>>> # 调用lindex返回str
>>> s_key = interp.eval('lindex $list0 0')
1.2.2. 通过setvar给变量赋值
>>> interp.setvar('s_tmp', 'this is a tmp string')
1.2.3. 通过getvar得到变量的值
>>> interp.getvar('s_tmp') # 'this is a tmp string'
>>>
>>> s_tmp_var = 's_tmp'
>>> interp.getvar(s_tmp_var) # 'this is a tmp string',使用变量名代替's_tmp'
1.3. 时间
感觉datetime模块专业些
1.3.1. time模块
时间元组: (年,月,日,时,分,秒,周几,年中第几天,是否夏令时),手工指定时,最后3项可以指定为0;
时间戳:指定时间距1970-01-01 00:00:00总秒数,float型数;
>>> import time
1.3.1.1. 求当前时间戳
>>> time.time() # 1531722744.1899934,float型数
1.3.1.2. 求给定时间的时间戳(输入时间元组)
>>> t = (2018,7,16,14,38,59,0,0,0) # 时间元组,最后3项可以指定为0
>>> time.mktime(t) # 1531723139.0,给定时间的时间戳,注意参数只有一个而不是9个
1.3.1.3. 按指定格式显示当前时间,返回字符串
>>> time.strftime('%Y-%m-%d %H:%M:%S') # '2018-07-16 14:54:26',返回str
1.3.1.4. 指定时间字符串,按指定格式拆分为数组
>>> str = '2018-07-1615:20:00'
>>> time.strptime(str, '%Y-%m-%d %H:%M:%S') # 返回time.struct_time
返回time.struct_time(tm_year=2018, tm_mon=7, tm_mday=16, tm_hour=15, tm_min=20, tm_sec=0, tm_wday=0, tm_yday=197, tm_isdst=-1)
如果时间格式串与字符串不匹配会报告错误:time data xxx does not match format ‘%xxx’
1.3.1.5. 显示英文时间
>>> t = (2018,7,16,14,38,59,0,0,0)
>>> time.asctime(t) # 'Mon Jul 16 14:38:59 2018',返回str
1.3.1.6. 进程挂起1s时间
>>> time.sleep(1)。
1.3.1.7. 格式化字符串
格式 | 说明 |
---|---|
%y | 两位数年份(00-99) |
%Y | 四位数年份(0000-9999) |
%m | 月份(01-12) |
%d | 月内的一天(0-31) |
%H | 24小时制小时数(0-23) |
%I | 12小时制小时数(01-12) |
%M | 分钟数(00=59) |
%S | 秒(00-59) |
%a | 本地简化星期名称 |
%A | 本地完整星期名称 |
%b | 本地简化的月份名称 |
%B | 本地完整的月份名称 |
%c | 本地相应的日期表示和时间表示 |
%j | 年内的一天(001-366) |
%p | 本地A.M.或P.M.的等价符 |
%U | 一年中的星期数(00-53)星期天为星期的开始 |
%w | 星期(0-6),星期天为星期的开始 |
%W | 一年中的星期数(00-53)星期一为星期的开始 |
%x | 本地相应的日期表示 |
%X | 本地相应的时间表示 |
%Z | 当前时区的名称 |
%% | %号本身 |
1.3.2. datetime模块
时间元组: (年,月,日,时,分,秒,微秒),注意这个时间元组有7个元素;
时间戳:给定的时间距离开始时间(1970-01-01 00:00:00)总秒数,float型数;
datetime模块中有一个datetime类,所有的信息都存储在这个类中
1.3.2.1. 初始化datatime类
>>> import datetime
>>> dt = datetime.datetime # 给datetime类一个别名
>>> type(dt)
# <class 'type'>
1.3.2.2. 得到一个指定具体时间的datetime类dt0
>>> dt0 = dt(2018,7,16,17,7,30,1)
>>> type(dt0)# 可以从dt0中取想要的数据
# <class 'datetime.datetime'>
1.3.2.3. 分别取年、月、日、时、分、秒、微秒
>>> dt0.year# 取年份, 返回值为int
2018
>>> dt0.month # 取月份, 返回值为int
7
>>> dt0.day# 取日期,返回值为int
16
>>> dt0.hour# 取时,返回值为int
14
>>> dt0.minute# 取分,返回值为int
29
>>> dt0.second# 取秒,返回值为int
20
>>> dt0.microsecond# 取微秒,返回值为int
253127
1.3.2.4. 取date和time
>>> dt0.date()# 取年月日, 返回datetime.date类
datetime.date(2018,7,16)
>>> dt0.time()# 取时间, 返回datetime.time类
datetime.time(17,7,30,1)
1.3.2.5. 取周几、日历
>>> # 取周几:
>>> dt0.weekday()#周一为0, 返回值为int
0
>>> dt0.isoweekday() #周一为1, 返回值为int
1
>>> dt0.isocalendar() # 取日历, 返回tuple,
(2018, 29,1)# 含义:(年,第几周,周几);
1.3.2.6. 公元天数换算
>>> dt0.toordinal() # 到公元元年的天数, 返回值为int
736891
>>> dt1 = dt0.fromordinal(54) # 指定到公元元年的天数,算datetime,返回datetime类
>>> dt1
datetime.datetime(1,2,23,0,0)
1.3.2.7. 取当前时间、零时区时间
>>> # 取当前时间:返回datetime类
>>> dt2 = dt.today()
>>> dt2
datetime.datetime(2018,7,17,10,31,53,757945)
>>> dt3 = dt.now()
>>> dt3
datetime.datetime(2018,7,17,10,31,53,758002)
>>>
>>> # 取零时区时间:返回datetime类
>>> dt4 = dt.utcnow()
>>> dt4 # 中国是东8区,所以零时区时间=中国时间-8 (东边日出早,小时数值大)
datetime.datetime(2018,7, 17, 2, 31, 53, 758017)
1.3.2.8. 取时间的标准str
>>> dt0.isoformat() # 得到时间的标准str,返回值为str
'2018-07-16T17:07:30.1'
1.3.2.9. 时间戳
>>> dt0.timestamp() # 从datetime取时间戳: 返回float,小数位表示毫秒数
1531732050.000001
>>> dt5 = dt0.fromtimestamp(1531732650.000001) # 从时间戳取datetime: 返回datetime类
>>> dt5
datetime.datetime(2018,7,16,17,17,30,1)
1.3.2.10. 自定义格式时间、英文格式时间
>>> dt.strftime('%Y-%m-%d') # 按自定义格式返回时间str
'2018-07-16'
>>> dt.ctime() # 取英文格式的时间,返回str
'Mon Jul 16 17:07:30 2018'
1.3.2.11. 时间元组
>>> dt0.timetuple() # 得到9个元素的时间元组,
time.struct_time(tm_year=2018, tm_mon=7,tm_mday=16, tm_hour=17, tm_min=07, tm_sec=30,tm_wday=1, tm_yday=190,tm_isdst=-1)
1.3.2.12. 给定时间str,按时间格式拆开,返回datetime.datetime类
>>> str='2049-12-31 23:59:59'
>>> dt6 = dt.strptime(str, '%Y-%m-%d %X')
>>> dt6
datetime.datetime(2049,12,31,23,59,59)
1.3.2.13. datetime加减
>>> now = datetime.datetime.now()
datetime.datetime(2017,8,23,14,21,33,796979)
>>>
>>> now + datetime.timedelta(hours=10)
datetime.datetime(2017,8,24,0,21,33,796979)
>>>
>>> now - datetime.timedelta(days=1)
datetime.datetime(2017,8,22,14,21,33,796979)
>>>
>>> now + datetime.timedelta(days=2, hours=12)
datetime.datetime(2017,8,26,2,21,33,796979)
1.4. 进制转换
1.4.1. 使用bin/oct/hex、int
1.4.1.1. 十进制-> 其它进制
>>> #使用bin/oct/hex,输入int,返回str;
>>> bin(50) # '0b110010',十进制 -> 二进制,返回的值为字符串,以0b开头;
>>> oct(50) # '0o62',十进制 -> 八进制,返回的值为字符串,以0o开头;
>>> hex(50) # '0x32', 十进制 -> 十六进制,返回的值为字符串,以0x开头;
1.4.1.2. 其它进制-> 十进制
>>> s_bin = '110010'# 二进制str;
>>> i_int= int(str(s_bin), 2) # 50, 输入二进制str,返回十进制整数;
>>>
>>> i_int = int(str(62), base=8)# 50,输入八进制str,返回十进制整数;
>>> i_int = int(str(32), base=16) # 50,输入十六进制str,返回十进制整数;
1.4.2. 使用format
缺点是format的参数只能是各进制的整数,不能是str;
所有需要把参数使用int()处理后再使用format, 如:
‘{n:08b}’.format(n=int(s0, base=16))
1.4.2.1. 转为二进制
>>> '{:b}'.format(13) #输入十进制整数,输出二进制str,:b表示转为二进制;
'1101'
>>> '{:08b}'.format(13) #输入十进制整数,输出二进制str,:08b表示转为二进制,宽度为8,不足补0;
'00001101'
>>> '{:08b}'.format(0x000D)#输入十六进制整数,输出二进制str;
'00001101'
>>> s0='0xd'
>>> '{n:08b}'.format(n=int(s0, base=16)) #输入十六进制str, 转为二进制, 中间需要经过int()处理
'00001101'
1.4.2.2. 转为八进制
>>> '{:o}'.format(13) #输入十进制整数,输出八进制str,:o表示转为八进制;
'15'
>>> '{:08o}'.format(13) #输入十进制整数,输出八进制str,:08o表示转为八进制,宽度为8,不足补0;
'00000015'
>>> '{:08b}'.format(0xD)#输入十六进制整数,输出八进制str;
'00000015'
1.4.2.3. 转为十六进制
使用大写的:X, 可以转出的16进制字符.
>>> '{:x}'.format(13) #输入十进制整数,输出十六进制str,:x表示转为十六进制
'd'
>>> '{:04x}'.format(13) #输入十进制整数,输出十六进制str,:04x表示转为十六进制,宽度为4,不足补0
'000d'
>>> '{:04x}'.format(0b01101)#输入二进制整数,输出十六进制str;
'000d'
>>> '{:04x}'.format(int('0b01101', base=2)#输入二进制str,输出十六进制str;
'000d'
1.5. 格式化字符
1.5.1. 使用%
%的常用转换类型
转换 | 说明 | 示例 |
---|---|---|
d,i | 整型 | ‘%i’%(4.3) 返回’4’ |
u | 无符号整型 | |
f | 浮点型, m.dddd | ‘%5.3f’%(1/3) 返回’0.333’ |
e | 浮点型, m.dddde+/-xx | ‘%5.3e’%(1/3) 返回’3.333e-01’ |
E | 浮点型, m.ddddE+/-xx | ‘%5.3E’%(1/3) 返回’3.333E-01’ |
g | ||
c | char, 单字符 | ‘%c’%(78), 返回’N’ |
s | str或能用str()转换的数据 | ‘%s’%(1/3), 返回’0.3333333333333333’ |
% | 输入一个% | ‘30%%’%(), 返回’30%’ |
1.5.1.1. 对整数指定宽度
>>> n = 5
>>> s = '%8d'%(n)# '5',默认为右对齐;
>>> s = '%08d'%(n)# '00000005',前面补0;
>>> s = '%-8d'%(n)# '5', 使用负号,左对齐;
1.5.1.2. 通过变量指定宽度
>>> w = 8
>>> n = 5
>>> s = '%*d'%(w, n)# '5',默认右对齐;
>>> s = '%0*d'%(w, n) # '00000005',前面补0;
>>> s = '%-*d'%(w, n) # '5',左对齐;
1.5.1.3. 对小数指定宽度
只指定总宽度
>>> n = 3.1415926 # 整数部分1位,小数部分7位
>>> '%5f'%(n) # '3.141593' n长度超过5,所以不舍去bit,但为什么最后的6被四舍五入了?
>>> '%6f'%(n) # '3.141593' n长度超过6,所以不舍去bit,但为什么最后的6被四舍五入了?
>>> '%7f'%(n) # '3.141593' n长度超过7,所以不舍去bit,但为什么最后的6被四舍五入了?
>>> '%8f'%(n) # ' 3.141593' 整数部分2bit,小数部分6bit,共8bit;
指定总宽度和小数宽度
>>> n = 3.1415926 # 整数部分1位,小数部分7位
>>> '%5.0f'%(n) # '3',共5bit, 小数部分0bit,整数部分5bit,小数点0bit;
>>> '%5.1f'%(n) # '3.1',共5bit, 小数部分1bit,整数部分3bit,小数点1bit;
>>> '%5.3f'%(n) # '3.142',共5bit, 小数部分3bit,整数部分1bit,小数点1bit;
>>> '%5.4f'%(n) # '3.1416' 小数部分4bit,整数部分1bit,小数点1bit,超过了5bit,实际共6bit,相当于'%6.4f'%(n);
>>> '%5.5f'%(n) # '3.14159' 小数部分5bit,整数部分1bit,小数点1bit,超过了5bit,实际共7bit,相当于'%7.5f'%(n);
>>> '%05.1f'%(n) # '003.1' 小数部分1bit,整数部分3bit,小数点1bit,共5bit;
1.5.1.4. 通过变量指定总宽度和小数宽度
>>> w_all = 5
>>> w_frac = 1
>>> '%0*.*f'%(w_all, w_frac, n) # '003.1' 小数部分1bit,整数部分3bit,小数点1bit,共5bit;
1.5.2. 使用format
format是python2.6后增加的功能
1.5.2.1. 通过位置映射
>>> '{} and {}'.format('hello', 'world') # 'hello and world' ,不指定位置,按默认顺序;
>>> '{0} and {1} or {0}'.format('hello', 'world') # 'hello and world or hello' ,指定位置,位置可以重复使用;
1.5.2.2. 通过key映射
>>> '{name} is {age} years old'.format(age=18, name='Jim') # 'Jim is 18 years old'
1.5.2.3. 通过下标映射
>>> list_info = ['Jim', 18]
>>> '{0[0]} is {0[1]} years old'.format(list_info) # 'Jim is 18 years old'
>>> '{list_arg[0]} is {list_arg[1]} years old'.format(list_arg=list_info) # 'Jim is 18 years old'
1.5.2.4. 填充与对齐
语法: {:[填充符][对齐方式][宽度]}
对齐方式:’^‘表示居中,’<‘表示左对齐,’>'表示右对齐;
宽度: 通过数字或变量指定;
>>> '{s0:<10}'.format(s0='abcd') #左对齐
'abcd '
>>> '{s0:^10}'.format(s0='abcd') #居中对齐
' abcd '
>>> '{s0:>10}'.format(s0='abcd') #右对齐
' abcd'
>>> '{s0:0>10}'.format(s0='abcd') #不足补0
'000000abcd'
>>> '{s0:x^10}'.format(s0='abcd') #不足补x
'xxxabcdxxx'
>>> '{s0:x^{w}}'.format(s0='abcd', w=10) #通过变量指定宽度
'xxxabcdxxx'
>>> '{s0:{t}^{w}}'.format(s0='abcd',t='x', w=10) #通过变量指定填充字符, 好像只支持一个字符
'xxxabcdxxx'
>>> '{s0:{t}{d}{w}}'.format(s0='abcd',t='x', d='^', w=10) #通过变量指定对齐方式
'xxxabcdxxx'
out
1.5.2.5. 指定小数部分宽度
>>> '{:.3f}'.format(0.123456)# '0.123',.3f表示小数部分占3bit;
>>> '{:7.3f}'.format(0.123456) # '[ ][ ]0.123',7.3f表示小数部分占3bit,字符总宽度7bit;
>>> '{n:{w_all}.{w_frac}f}'.format(m=0.123456, w_all=7, w_frac=3) # '[ ][ ]0.123',通过变量指定宽度;
1.5.2.6. 添加千分位分隔符
>>> '{:,}'.format(1234567.89123) # 1,234,567.89123 , ':,'表示添加千分位分隔符;
1.6. 排序
1.6.1. list内置方法sort()
语法:sort(key=None, reverse=False)
参数:
key,一个函数,作用是指定比较的元素, 通常由lambda指定, 可以指定多个值lambda x: (x[0], x[1], x[2]);
reverse,bool类型,False升序,True降序, 默认升序;
说明:
sort方法会改变list本身, 并返回None, 所以不能这么写a = b.sort();
python3中,sort删除了cmp参数
例子:
>>> L0 = [('a', 1), ('b', 3), ('d', 2), ('c', 1)]
>>>
>>> # 默认排序
>>> L0.sort()
>>> L0
[('a', 1), ('b', 3), ('c', 1), ('d', 2)]
>>>
>>> # key=lambda x:x[1], 按L0元素(是一个tuple)的第1个元素排序,
>>> # 也可以指定key=lambda x:(x[1], x[0])进行多维排序
>>> L0.sort(key=lambda x:x[1])
>>> L0
[('a', 1), ('c', 1), ('d', 2), ('b', 3)]
>>>
>>> # 降序排序
>>> L0.sort(reverse=True) # 默认按升序排序,通过reverse=True按降序排列;
>>> L0
[('d', 2), ('c', 1), ('b', 3), ('a', 1)]
>>>
>>> # sort返回值是None, 即list.sort()没返回任何对象
>>> print(L0.sort())
None
1.6.2. 全局方法sorted()
语法:sorted(iterable, key=None, reverse=False)
参数:
iterable: 可迭代对象
key:sorted是一个高阶函数,可以接收一个key函数来自定义排序,key指定的函数作用于list的每一个元素上,并根据key函数的返回值进行排序, 参见list的内置函数sort的key参数.
reverser:bool类型,False升序,True降序; 默认升序.
注意:sorted方法不改变原序列,而是返回一个新的序列;
例1:按绝对值排序、按忽略大小写排序、降序排序
>>> sorted([36,15,-12,9,-21], key=abs) #按绝对值大小排序;
[9, -12, 15, -21, 36]
>>> sorted(['bob', 'About', 'Zoo', 'Credit'], key=str.lower) # 按忽略大小写排序;
['About', 'bob', 'Credit', 'Zoo']
>>> sorted(['bob','About','Zoo','Credit'], key = str.lower, reverse=True) # 按忽略大小写反向排序;
['Zoo', 'Credit', 'bob', 'About']
例2:按字典的key/value排序
>>> d={
}
>>> d['a'] = 3
>>> d['b'] = 4
>>> d['c'] = 2
>>> d['d'] = 1
>>> sorted(d.items(), key=lambda x:x[0]) #按key排序,返回[('a',3),('b',4),('c',2),('d',1)]
>>> sorted(d.items(), key=lambda x:x[1]) #按value排序,返回[('d',1),('c',2),('a',3),('b',4)]
例3:按多条件排序
>>> d0 = {
}
>>> d0['id0'] = {
'score':90, 'name':'name1', 'age':14}
>>> d0['id1'] = {
'score':90, 'name':'name3', 'age':12}
>>> d0['id2'] = {
'score':60, 'name':'name2', 'age':13}
>>> d0['id3'] = {
'score':90, 'name':'name3', 'age':11}
>>>
>>> list_id_sorted = sorted(
... d0.keys(), # 对d0.keys()排序, 所以返回的是id组成的list.
... key=lambda s_id:(
... -d0[s_id]['score'], # 按分数逆序排列,-表示逆序
... d0[s_id]['name'] , # 按姓名顺序排列
... s_id , # 按学号顺序排列
... )
... )
...
>>> for s_id in list_id_sorted:
... print(f'{d0[s_id]['score']} {d0[s_id]['name']} {s_id}')
...
90 name1 id0 # 90分排在前;
90 name3 id1 # 同样90分,按姓名排序;
90 name3 id3 # 同样90分,同样name3,按学号排序;
60 name2 id2 # 60分排在后;
1.6.3. key参数
key参数
可以是一个简单的函数, 比如key=str或key=str.lower,
可以是一个通过lambda指定的函数 key=lambda x:(x[0], x[1])
可以是一个自定义的函数:
def sort_str(x):
m = re.match(r'^(\S+?)(\d+)$', x)
if m:
_name = m.group(1)
_idx = int(m.group(2))
else:
_name = x
_idx = 0
return _name, idx # 先按前导字符排序, 后按后缀数字排序
# 这样'a2'排在'a10'前面, 'a*'排在'b0'前面.
L0 = ['a2', 'b3', 'a1', 'b20', 'a0', 'a10', 'a9', 'b0']
L1 = sorted(L0, key=sort_str)
print(L1) # ['a0', 'a1', 'a2', 'a9', 'a10', 'b0', 'b3', 'b20']
1.7. 处理命令行参数
1.7.1. 使用步骤
使用步骤如下:
# 导入模块
import argparse
# 获取parser, description文本会显示在help信息中
parser = argparse.ArgumentParser(description='args discrip')
# 添加选项, 具体选项类型见后面各节
parser.add_argument('-a')
# 解析选项
args = parser.parse_args(sys.argv[1:])
# 使用选项
print(args.a)
对sys.argv[1:]的说明:
sys.argv # 一个列表,存储命令行参数.
sys.argv[0] # 脚本名.
sys.argv[1:] # 命令行参数.
sys.argv[1][2:] # 截取第一个参数第2bit之后的内容;
1.7.2. 位置参数
# 位置参数可以实现类似于vcs a.v b.v的选项处理,
# 如下例, vfiles是位置参数,不需要使用'-vfile 或者-xx'这种形式指定选项内容;
# default=[] 表示默认参数为空list;
# nargs='*' 表示可以是0个或多个参数;
>>> parser.add_argument('vfiles', type=str,default=[], nargs='*')
_StoreAction(optine_strings=[], dest='vfiles', nargs='*', const=None, default=[], Type=<class 'str'>, choices=None, help=None, metavar=None)
1.7.3. flag类型的选项(选项本身无参数)
flag类型选项本身无参数, 根据"命令行是否有该选项" 和 “该选项声明值/默认值” 来决定选项实际值(注意, 并不是声明选项, 则该选项为True, 不声明为False, 而是内部可配置):
>>> parser.add_argument(
... '-a', # 选项名称
... action='store_true', # 如果声明-a, 则a=True;
... default=False # 如果不声明(默认)-a, 则a=False;
... )
_StoreTrueAction(optine_strings=['-a'], dest='a', nargs=0, const=True, default=False, Type=None, choices=None, help=None, metavar=None)
>>>
>>> parser.add_argument(
... '-b',
... '--b_long_opt', # b有额外的长选项名称: --b_long_opt
... action='store_false', # 如果声明-b, 则b=False
... default=True, # 如果不声明(默认)-b, 则b=True
... dest='b_new_name' # 内部使用b_new_name取用该选项(而不能使用b)
)
_StoreTrueAction(optine_strings=['-b', '--b_long_opt'], dest='b_new_name', nargs=0, const=False, default=True, Type=None, choices=None, help=None, metavar=None)
注意,不会有以下两种情况,因为这两种情况下,无论选项是否定义,内部得到的值都一样,没有意义;
>>> # action='store_true', default=True,声明选项和默认值都是True
>>> # action='store_false', default=False,声明选项和默认值都是False
通过parse一个内部数组来进行验证,实际使用中是parse真正的命令行数组sys.argv[1:], 注意sys.argv[0]表示的是脚本名称;
测试1:#-a -b都没声明,所以都是default值
>>> lst_args=[]
>>> args = parser.parse_args(lst_args)
>>> args.a # 未声名-a,所以args.a的值为default值False;
False
>>> args.b_new_name # 未声名-b,所以args.b_new_name值为默认值True;
True
>>> args.b # 由于使用了dest, 所以args.b会报错, 只能使用args.b_new_name获取
AttributeError: 'Namespace' object has no sttribute 'b'
测试2:-a -b都声明,所以都是action store值
>>> lst_args=['-ab'] # -a和-b是短选项, 可以合并使用'-ab'表示'-a' '-b'
>>> args = parser.parse_args(lst_args)
>>> args.a # 声名了-a,所以args.a的值为声明值True;
True
>>> args.b_new_name # 声名了-b,所以args.b_new_name值为声明值False;
False
测试3:使用长选项,-a -b都声明,所以都是store值
>>> lst_args=['-a', '--b_long_opt'] # --b_long_opt是长选项, 需要使用双短线('--')进行声明
>>> args = parser.parse_args(lst_args)
>>> args.a # 声名了-a,所以args.a的值为声明值True;
True
>>> args.b_new_name # 声名了-b,所以args.b_new_name值为声明值False;
False
1.7.4. 必选选项(选项必须声明, 不声明会报错)
>>> parser.add_argument(
... '-c', # 选项名称
... type=int, # 选项类型是整数
... required=True # 选项是必选选项
)
_StoreAction(optine_strings=['-c'], dest='c', nargs=None, const=None, default=None, Type=<class 'int'>, choices=None, help=None, metavar=None)
>>>
>>> # 选项-c必须声明,否则报错:error:the following argument are required:-c
>>> lst_args=['-c', '3']
>>> args = parser.parse_args(lst_args)
>>>
>>> # 选项-c类型为int,所以str '3'传到args.c时,会转类型为int 3;
>>> print(args.c)
3
1.7.5. 可选选项,可带默认值
-d 为str类型的可选选项,默认值为’default_d’
-d 为str类型的可选选项,默认值为'default_d'
>>> parser.add_argument(
... '-d', # 选项名
... type = str, # 选项类型
... required = False, # '-d'是可选选项
... default = 'default_d' # '-d'不声明时, 默认值为'default_d'
)
_StoreTrueAction(optine_strings=['-d'], dest='d'