数字、日期和时间
一、对数值进行取整
将浮点数取整到固定的小数位:roung(value, ndigits),ndigits可以是负数,取整到十位、百位、千位等。
>>> round(1.456, 2) # 1.46
>>> round(16743, -3) # 17000
>>> format(1.2345, '0.3f') # 1.235
二、精确的小数计算
浮点数无法精确表达出所有的十进制小数位。
0.3的二进制表示是无限循环,所以如果要精确表示0.3,计算机需要无限个二进制位才能做到。
然而计算机的内存、CPU寄存器等等硬件单元都是有限的,只能表示有限的二进制位。
>>> from decimal import Decimal
>>> Decimal('4.2') + Decimal('2.1') # Decimal('6.3')
三、数值做格式化输出
使用内建的format()函数即可。
>>> 'The value is {:0,.2f}'.format(123456.789) # 123,456.79
四、二进制、八进制和十六进制数
将一个整数转换为二进制、八进制和十六进制的文本字符串形式,分别使用内建的bin()、oct()、hex()函数即可。
>>> x = 1234
>>> bin(x) # '0b10011010010'
>>> oct(x) # '0o2322'
>>> hex(x) # '0x4d2'
不希望出现0b、0o、0x这样的前缀,可以使用format()函数
>>> format(x, 'b'), format(x, 'o'), format(x, 'x')
转换回10进制:
>>> int('4d2', 16) # 1234
确保八进制数前添加0o前缀:
>>> os.chmod('script.py'. 0o755)
五、字节串中打包和解包大整数
>>> int.from_bytes(data, 'little')
>>> x.to_bytes(16, 'big')
六、复数运算
复数通过complex(real, imag)函数来指定,或者通过浮点数再加上后缀j来指定。
>>> a = complex(2, 4) # (2+4j)
>>> b = 3 - 5j
>>> a.real, a.imag, a.conjugate() # 实部、虚部以及共轭值
求正弦、余弦或平方根使用cmath模块
>>> cmath.sin(a), cmath.cos(a), smath.exp(a)
七、处理无穷大和 NaN(Not a number)
检测是否出现该值用math.isinf()和math.isnan()函数
>>> float('inf'), float('-inf'), float('nan')
(1)无穷大值在数学计算中会进行传播
(2)某些特定的操作会导致未定义的行为并产生NaN的结果
(3)NaN会通过所有的操作进行传播
八、分数的计算
fractions模块处理设计分数的数学计算问题
>>> form fractions import Fraction
>>> a = Fraction(5, 4) # 5/4
>>> a.numerator, a.denominator # 5, 4
>>> float(a)
>>> x = 3.75
>>> y = Fraction(*x.as_integer_ratio()) # Fraction(15, 4)
十一、随机选择
(1)从序列中挑选元素:
>>> random.choice([1, 2, 3, 4, 5])
(2)序列中随机取N个元素:
>>> random.sample(values, N)
(3)打乱序列顺序:
>>> random.shuffle(values)
(4)产生随机整数
>>> random.randint(0,10) # 0~10范围
(5)产生0~1均匀分布的浮点数值:
>>> random.random()
(6)由N个随机比特位所表示的整数:
>>> random.getrandbits(N)
(7)random模块采用马特赛特旋转算法,这是一个确定性算法,但是可以通过 random.seed() 函数修改初始的种子值。
十二、时间换算
利用 datetime 模块来完成不同时间单位间的换算。
>>> from datetime import timedelta
>>> a = timedelta(days=2, hours=6, minutes=6)
>>> from datetime import datetime
>>> b = datetime(2019, 9, 11)
>>> c = b - a
>>> datetime.today()
处理时区、模糊时间范围、计算节日的日期使用 dateutil 模块,同时解决datetime不能计算月份的问题。
>>> from dateutil.relativedelta import relativedelta
>>> a + relativedelta(months=+1)
>>> d = relativedelta(b, a) # 计算相差的天数
>>> d.months, d.days
十三、计算上周 X的日期
使用datetime模块完成计算例子:
def get_previous_byday(dayname, start_date=None): weekdays = ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'] if start_date is None: start_date = datetime.today() day_num = start_date.weekday() day_num_target = weekdays.index(dayname) day_ago = (7 + day_num - day_num_target) % 7 if day_ago == 0: day_ago = 7 target_day = start_date - timedelta(days=day_ago) return target_day
使用dateutil模块计算
>>> from datetime import datetime
>>> from dateutil.relativedelta import relativedelta
>>> from dateutil.rrule import *
>>> d = datetime.today()
>>> d+relativedelta(weekday=FR) # Next Friday
>>> d+relativedelta(weekday=FR(-1)) # Last Friday
十四、找出当月的日期范围
循环迭代当月中的每个日期。
from datetime import datetime,timedelta import calendar def get_month_range(start_day=None): if start_day is None: start_day = datetime.today().replace(day=1) _, days_in_month = calendar.monthrange(start_day.year, start_day.month) end_date = start_day + timedelta(days=days_in_month) return (start_day,end_date) a_day = timedelta(days=1) first_date, last_date = get_month_range() while first_date < last_date: print(first_date) first_date += a_day
(1)计算出月份中第一天的日期:datetime对象的replace(day=1)方法进行替换。
(2)calendat.monthrange() 函数,找出待求解的月份中有多少天,返回第一个工作日的星期(返回值0~6)和当月的天数(28~31)。
生成器实现例子:
from datetime import datetime,timedelta def get_range(start_day,end_day,step): while start_day < end_day: yield start_day start_day += step for k in get_range(datetime.today(),datetime(2019,10,1),timedelta(days=1)): print(k)
十五、将字符串转换为日期
datetime.strptime()方法支持许多格式化代码,如%Y代表4为数字表示的年份,%m代表2位数字月份,%d代表日期。
>>> from datetime import datetime
>>> text = '2019-9-11'
>>> datetime.strptime(text, ‘%Y-%m-%d’)
但是datetime.strptime()性能表现糟糕体现在处理各种各样的系统区域设置。如果事先知道日期格式,可以自己编写代码:
def parse_ymd(str_date): year_s, mon_s, day_s = str_date.split('-') return datetime(int(year_s), int(mon_s), int(day_s))
十六、涉及时区的日期处理
时区名称:pyzt.country_timezones,这是一个字典,使用ISO3166国家代码作为key来查询所属时区。
>>> pyzt.country_timezones['CN'] # ['Asia/Shanghai', 'Asia/Urumqi']
时区计算:先将本地时间-》UTC时间,UTC时间进行运算-》本地时间
>>> from pytz import timezone
>>> central = timezone('Asia/Shanghai')
>>> loc_d = central.localize(datetime.today())
>>> utc_d = loc_d.astimezone(pytz.utc)
>>> utc_d + timedelta(minutes=30)
>>> later_utc = utc_d + timedelta(minutes=30)
>>> later_utc.astimezone(central)