数字、日期和时间

 

一、对数值进行取整

  将浮点数取整到固定的小数位: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)

 

posted @ 2019-09-11 15:18  5_FireFly  阅读(603)  评论(0编辑  收藏  举报
web
counter