全民一起玩Python提高篇第三课:深入数据类型与语法细节(上)

decimal

如果想把一个十进制小数表示为有限位数的二进制小数,必须确保该十进制小数可以分解为 2^-1 、2^-2 、2^-3 ……
的组合,否则在二进制中将是一个无限位的小数。比如十进制小数0.1在二进制中就是一个无限小数。 由于Python遵循 IEEE 754
浮点数标准中的双精度类型格式,所以无论对于怎样的小数都使用64位二进制保存。因此对于0.1这样的小数,Python会自动截断后面的无限位,只保留前面几十位。因此Python中实际保存的二进制0.1只是一个近似值,转换回十进制后会存在微小的误差,从而导致计算精度错误。

可以使用内置函数 round(原始数值, 保留小数位数) 实现四舍五入。而Python3 中则使用“银行家舍入法”,即“尾数为5时,前一位奇进偶不进”。> 能够保证均值保持不变,不失真

由于二进制转换误差的存在,类似 2.675 的数字在计算机中实质上相当于 2.6749999… ,所以使用 round
四舍五入的结果往往不同于预期。因此在精度需求较高的场合要慎用round

解决方案
用Decimal,可以让数字以真正十进制来进行表示

from decimal import Decimal
x=Decimal('2.37')
y=Decimal('2.14')
print(x+y)
4.51
print(Decimal(2.37)+Decimal(2.14))
#放到里面的一定要是字符串,否则要被转为二进制
4.510000000000000230926389122

Decimal 类型的数字不能与普通小数直接运算;含有 Decimal 型数字的计算式,计算结果也是 Decimal 类型,可以使用 float() 等转换为普通数字。

可以使用内置函数 format(原始数字,格式说明) 按照规定格式生成数字字符串。典型的格式说明是一个形如 “0.2f” 的字符串,其中 0 代表不特别指定结果长度、2 代表结果中保留两位小数、f 代表结果仍为普通小数形式。

format(3.141,'0.2f')
'3.14'

format 函数的格式说明参数可以使用类似 “5.2f” 的形式,指定结果字符串的长度。如果实际结果数字未达到该长度(比如小于5),则空位自动补为空格;如果超出指定长度(比如大于5),也不会强制截断为5,实际结果长度就是数字长度。

format(3.1415926,'5.2f')
' 3.14'

format 函数的格式说明参数中,还可以使用一下常用技巧:
使用 “<5.2f” 的形式,让结果中的数字在字符串(本例长度为5)中靠左对齐;
使用 “>5.2f” 的形式,让结果中的数字在字符串(本例长度为5)中靠右对齐;
使用 “^5.2f” 的形式,让结果中的数字在字符串(本例长度为5)中居中对齐;
使用 “0.2e” 的形式,让结果以科学计数法形式表示,其中底数保留两位小数。
使用 “0.2%” 的形式,让结果以百分数形式表示。比如 format( 1.234567 , ‘0.2%’)会得到 ‘123.46%’ 。(本条内容在视频中未提到)

对于 32 位计算机,可以一次处理 4 个字节的数据,所以在 32 位计算机中一般采用4个字节(32位二进制)表示一个整数,以发挥计算性能。同理,64位计算机中一般用 8 个字节表示一个整数。

Python3 中则将所有整数都统一视作 “长整型”

可以使用 float(‘inf’) 和 float(’-inf’) 表示正负无穷大,实际运算时的结果也与数学中的无穷大运算相同
对于无法得出结果的计算式(比如无穷大相除),Python 以特殊值 nan 代表结果。如果需要判断某个运算结果是否为 nan, 不能直接写 if x == nan ,而要使用 math 模块的 isnan 函数,比如 if math.isnan(x) 。该函数返回一个逻辑值,代表参数是否等于 nan 。

x=float('-inf')
y=100
x>y
False
x/y
nan

题目:检验判断语句

某人编写了下面这个程序,用于在屏幕上输出 0.1、0.2、0.3、…、0.8 共计8个小数。请先分析这个程序的运行结果,然后在自己电脑上实际运行它,观察真实结果并思考原因。
x = 0.1
while x!=0.8:
print( x )
x += 0.1
接下来,某人在发现该问题后,决定将 x!=0.8 修改为 x<0.9 ,请思考并试验,看看这样修改后是否能够正确输出结果?

答:均不能输出正确结果
x!=0.8,会变成死循环,因为得不到0.8
x<0.9会多循环一次,因为加到0.9实际为0.899999…
小数有误差,整数没有

逻辑运算

浮点数float

浮点数是一种类似科学计数法的数字表示方式,可以存放小数、整数等各种形式数字,Python中浮点数采用8个字节(64位二进制)空间
因为浮点数的存储分为三部分,第一部分放幂指数的正负号,第二部分放幂指数,第三部分放科学计数法的主干部分。因为要还原数据,就需要根据前两部分,让小数点跟着浮动,所以叫浮点数。

复数complex

x=1+2j+3+4j
x
(4+6j)

复数类型数据可以直接执行各种运算,格式和语法与普通数字相同,但是虚部数字和j要连着写,分开写就会出错

如果复数的实部为0、虚部为1,也就是 i ,那么在python中不能直接写 j ,否则Python会认为 j 是某个变量或函数的名字。正确的写法是 1j 或 0+1j

求绝对值函数abs()
面对复数时,是求他的模

abs(3+4j)
5.0

取实部虚部和共轭

x=3+4j
x.real
3.0
x.imag
4.0
x.conjugate()
(3-4j)

题目:精确乘法

请处理用户输入的任何十进制小数。

def get_len(s):
    loc=s.find('.')
    if loc==-1:
        result=0
    else:
        result=len(s)-loc-1
    return result
def change(s):
    s=int(s.replace(".",""))
    return s
x=str(input('请输入x的值\n'))
y=str(input('请输入y的值\n'))
dec=get_len(x)+get_len(y)
x=change(x)
y=change(y)
z=str(x*y)

if dec>0:
    if len(z)<dec:
        z ='0'*(dec-len(z)+1) + z
    # 完成必要的补零后,即可用负数切片操作,在小数前面插入小数点。
    z = z[:-dec] + '.' + z[-dec:]
print(z)

boolean

布尔类型(逻辑类型)其实是整数类型(int)的子类,True和False在算术式中会被自动视作1和0
这里和C语言当时学的一样
if 0:
else:
这种写法,就是意味着0代表False,实际执行的就是else后面的

0和“空”(空字符串、空列表、空对None、空元组、空集合 …… )含义的值,会在 if 等需要逻辑值的场合中被自动认为 False

内置函数 bool() 可以根据前述规则得到某个数据的对应逻辑值。需要注意的是:根据前述规则,bool(“False”) 的结果是True而非False。

需要注意的是:根据前述规则,bool(“False”) 的结果是True而非False。
任何非空字符串都是True

时间

要统计程序运行时间
可以在开头和末尾分别写上

t1=time.time()
t2=time.time()
print('一共用时',t2-t1,'秒')

datetime函数

datetime模块中的datetime类提供了更加易用的时间表示形式。该类对象的now()方法可以返回当前系统时间,而其 year 、minute 等属性 可以返回该日期的年份、分钟等数字。

>>> from datetime import datetime
>>> h2=datetime.now()
>>> print(h2)
2020-03-28 10:25:31.123200

可以使用datetime模块中datetime类的strftime()方法将日期映射为任意格式的字符串

h2.strftime('%Y-%m-%d-%h-%M')
#单引号一定要加
'2020-03-28-Mar-25'

为了加载中文显示
要先导入

import locale
locale.setlocale(locale.LC_CTYPE,'chinese')

将字符串转为标准时间格式

s='3月28日,2020年'
d=datetime.strptime(s,'%m月%d日,%Y年')
#strptime('待转字符串,该字符串格式')
str(d)
'2020-03-28 00:00:00'

借助第三方包来实现时间日期的加减

>>> from datetime import datetime
>>> d2=datetime(1999,12,31)
>>>from dateutil.relativedelta import relativedelta
>>>k=relativedelta(years=500)
>>>d3=d2+k
>>>print(d3)
2499-12-31 00:00:00

在这里插入图片描述
只有字符串,所以就会等距摆放
可以按一下来做调整

import  matplotlib.pyplot as plt
from datetime import datetime
plt.rcParams['font.sans-serif']=['Microsoft Yahei']
plt.rcParams['axes.unicode_minus']=False
#设置字体,确保负号正确显示
sales=[5,22,48,78]
dates=['20-03-01','20-03-12','20-03-16','20-03-31']
#创建横纵坐标列表
days=[]
for d in dates:
    delta=datetime.strptime(d,'%y-%m-%d')-datetime.strptime(dates[0],'%y-%m-%d')
    days.append(delta.days)
plt.grid()
plt.title('销量')
plt.xticks(days,dates)
#第一个参数为真实刻度,第二个为刻度标签
plt.plot(days,sales)
plt.show()
#显示

在这里插入图片描述

短路机制

True or (True/False)
看到True 就不会计算后面为真还是假了,直接就判断表达式为真,后面就叫做被短路
同样的
False and (True/False)
看到False了,那么整个句子为False,也会启动短路机制,不会看后面的

题目:计算平均寿命

编写程序读取该文件的内容,并计算明清两代皇帝的平均寿命是多少天(平均值四舍五入为整数即可,不需要小数),约合多少年

在这里插入图片描述

import xlwings as xw
import xlwt
from datetime import datetime
import locale
locale.setlocale(locale.LC_CTYPE,'chinese')
app = xw.App()
wb = app.books.open('E:\拷贝过来的文件\全民一起玩Python\MyProject\皇帝寿命.xlsx')
dates= wb.sheets[0].range('B1:C22').value
#创建横纵坐标列表
days=[]
years=[]
for d in dates:
    delta=datetime.strptime(d[1],'%Y年%m月%d日')-datetime.strptime(d[0],'%Y年%m月%d日')
    days.append(delta.days)
    years.append(format((delta.days/365),'0.2f'))
avg=sum(days)/len(days)
wb.sheets[0].range('A23').value=format((avg/365),'0.2f')
wb.sheets[0].range('D1').options(transpose=True).value=days
wb.sheets[0].range('E1').options(transpose=True).value=years
print(days)
wb.save()
app.quit()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值