处理数字、日期和时间

Python 2020-07-01 1117

1.数值取整

round()

>>> round(3.6)  
4  
>>> round(3.61, 1)  
3.6  

round()可以设置所取的小数位数。

2.精确小数计算

decimal

>>> from decimal import Decimal  
>>> a = Decimal(3.6)  
>>> b = Decimal('4.1')  
>>> a+b  
Decimal('7.7')  

decimal模块主要功能是允许控制计算过程的各个方面,包括数字的位数和四舍五入。

>>> from decimal import localcontext  
>>> a = Decimal('1.3')  
>>> b = Decimal('1.5')  
>>> print(a/b)  
0.8666666666666666666666666667  
>>> with localcontext() as ctx:  
    ctx.prec = 3  
    print(a/b)

0.867  

3. 二进制、八进制、十六进制

将一个整数转为二进制、八进制、十六进制,可以分别使用bin(),oct(),hex()。

>>> x = 123  
>>> bin(x)  
'0b1111011'  
>>> oct(x)  
'0o173'  
>>> hex(x)  
'0x7b'  

不希望出现0b,0x,0o这样的前缀,可以使用format().
format同样可以转进制。

>>> format(x, 'x')  
'7b'  
>>>format(x, 'o')  
173  

由进制转为整数。
16进制转整数:

>>> int(format(x, 'x'), 16)  
123  

4.字节串解包和打包大整数

from_bytesh和to_bytes

>>> data = b'\x00\x124V\x00x\x90\xab\x00\xcd\xef\x01\x00#\x004'  
>>> len(data)  
16  
>>> int.from_bytes(data, 'little')  # 打包  
69120565665751139577663547927094891008  
>>> int.from_bytes(data, 'big')  
94522842520747284487117727783387188  
>>> x = 69120565665751139577663547927094891008  
>>> x.to_bytes(16, 'big') # 解包  
b'4\x00#\x00\x01\xef\xcd\x00\xab\x90x\x00V4\x12\x00'  
>>> x = 94522842520747284487117727783387188  
>>> x.to_bytes(16, 'little')  
b'4\x00#\x00\x01\xef\xcd\x00\xab\x90x\x00V4\x12\x00'  

方法2:
struct模块,该模块虽然可以完成解包操作,但是可解包的整数大小有限制。解包大整数,需要先拆分,在合并。

>>> data = b'\x00\x124V\x00x\x90\xab\x00\xcd\xef\x01\x00#\x004'  
>>> hi, lo = struct.unpack('>QQ', data)  
>>> (hi << 64) + lo  
94522842520747284487117727783387188  

<< 左移运算 90 << 2 = 90 * 2 * 2 =360
>> 右移运算 90 >> 1 = 45
如果将一个整数打包成字节串,但字节大小不合适的话就会得到一个错误的信息。可以使用int.bit_length()方法来确定需要用到多少位才能保存这个数。

>>> x = 523**23  
>>> x  
335381300113661875107536852714019056160355655333978849017944067  
>>> x.to_bytes(16, 'little')  
Traceback (most recent call last):  
  File "<pyshell#76>", line 1, in <module>  
    x.to_bytes(16, 'little')  
OverflowError: int too big to convert  
>>> x.bit_length()  
208  
>>> nbytes, rem = divmod(x.bit_length(), 8)  
>>> if rem:  
    nbytes += 1

>>> x.to_bytes(nbytes, 'little')  
b'\x03X\xf1\x82iT\x96\xac\xc7c\x16\xf3\xb9\xcf\x18\xee\xec\x91\xd1\x98\xa2\xc8\xd9R\xb5\xd0'  

5.处理无穷大和NaN

通过math.isinf()和math.isnan()来判断无穷大和NaN.
NaN可以通过所有的操作,但是没有异常

>>> a = float('inf')  
>>> b = float('-inf')  
>>> c = float('nan')  
>>> a  
inf  
>>> import math  
>>> math.isinf(a)  
True  
>>> math.isnan(c)  
True  

6.分数操作

fractions模块可以用来处理涉及分数的数学计算问题。

>>> from fractions import Fraction  
>>> a =Fraction(5, 4)  
>>> a  
Fraction(5, 4)  
>>> b = Fraction(7, 16)  
>>> a + b  
Fraction(27, 16)  
>>> print(a+b)  
27/16  
>>> c = a*b  
>>> c  
Fraction(35, 64)  
>>> c.numerator  # 分子  
35  
>>> c.denominator # 分母  
64  
>>> float(c)  
0.546875  
>>> print(c.limit_denominator(5))  #通过限制分母的大小,取得一个接近c的一个近似值  
1/2  

7.处理大型数组

8.矩阵和线代计算

都是通过numpy实现,后期有专讲

9.随机选择(伪随机数)

random模块生成的都是伪随机数,不可用于加密数据。
使用secrets模块,这是python提供的生成安全随机数字用于管理密码的模块
序列中取一个随机数

>>> import random  
>>> values = [1, 4, 7, 2, 5, 8]  
>>> random.choice(values)  
4  
>>> random.choice(values)  
5  

序列中取N个元素

>>> random.sample(values, 3)  
[2, 7, 8]  

原地打乱顺序

>>> random.shuffle(values)  
>>> values  
[8, 4, 7, 5, 2, 1]  

产生随机的整数

>>>random.randint(0, 10)  
8  
>>>random.randint(0, 10)  
6  

0~1之间均匀分布的浮点数

>>> random.random()  
0.13320571567467077  
>>> random.random()  
0.5269396676667044  

产生由N个随机比特位所表示的整数,可使用random.getrandbits()

>>> random.getrandbits(128)  
261436695086523348737201426304790119919  
>>> len("261436695086523348737201426304790119919")  
39  
>>> bin(261436695086523348737201426304790119919)  
'0b11000100101011101110000000111111000110100110010110000001000100010101000101000011101011011001000101010100110100110100010111101111'  
>>> len('0b11000100101011101110000000111111000110100110010110000001000100010101000101000011101011011001000101010100110100110100010111101111')  
130  

10.时间换算

表示时间间隔,可以使用timedelta

>>> from datetime import timedelta  
>>> a = timedelta(days=2, hours=6)  
>>> a  
datetime.timedelta(days=2, seconds=21600)  
>>> b = timedelta(hours=4.5)  
>>> b  
datetime.timedelta(seconds=16200)  
>>> c = a + b  
>>> c  
datetime.timedelta(days=2, seconds=37800)  
>>> c.days  
2  
>>> c.seconds  
37800  
>>> c.total_seconds() / 3600 # 2天37800秒的总时间,total_seconds()计算的是总时间(秒)  
58.5  

表示特定的日期和时间

>>> from datetime import datetime  
>>> a = datetime(2012, 9, 23)  
>>> print(a + timedelta(days=10)) # 日期加10天  
2012-10-03 00:00:00  
>>> b = datetime(2012, 12, 21)  
>>> d = b -a  # 日期间隔  
>>> d.days  
89  
>>> now = datetime.now() # 当前时间  
>>> now  
datetime.datetime(2020, 7, 1, 20, 39, 13, 333733)  
>>> print(now + timedelta(minutes=10))  
2020-07-01 20:49:13.333733  

datetime模块可以正确处理闰年。

11.计算上周的时间

第一种方法:

from datetime import datetime, timedelta  
weekdays = ['Monday','Tuesday','Wednesday','Thursday',  
            'Friday','Saturday','Sunday']  
def get_previous_byday(dayname, start_date=None):  
    if start_date is None:  
        start_date = datetime.today()  
    day_num = start_date.weekday()  
    day_num_target = weekdays.index(dayname)  
    days_ago = (7 + day_num - day_num_target) % 7  
    if days_ago == 0:  
        days_ago = 7  
    target_date = start_date - timedelta(days = days_ago)  
    return target_date

print( datetime.today() )  
print( get_previous_byday('Monday') )  
print( get_previous_byday('Monday', datetime(2016, 8, 28)) )  

第二种方法:
第三方包,dateutil

from datetime import datetime  
from dateutil.relativedelta import relativedelta  
from dateutil.rrule import *  
d = datetime.now()  
print(d)  
print(d + relativedelta(weekday=FR))  
print(d + relativedelta(weekday=FR(-1)))  

12.当月的日期范围

求出本月的日期,计算出当月有多少天,在循环就可以求出。关键在于calendar.monthrange方法,该方法返回一个元组,其中(x, y),x代表星期(0-6),y代表,本月有多少天。

import calendar  
from datetime import date, timedelta  
x, y = calendar.monthrange(date.today().year, date.today().month)  
    for i in range(y):  
        print(date.today().replace(day=1) + timedelta(days=i))  

datetime对象的replace可以将day置为1

标签:Python

文章评论

评论列表

已有0条评论