纯享版笔记:http://8.140.123.56:9999/html/Chapter3.html 未经允许请勿转载。
In [1]:
#复习
import time
import turtle
turtle.fd(100)
turtle.rt(90)
turtle.fd(100)
turtle.rt(45)
turtle.fd(140)
turtle.done()
In [4]:
print(pow(2,100))
print(pow(2,200))
print(pow(2,499))
# print(pow(2,pow(2,15))) 太长了,所以注释掉
1267650600228229401496703205376 1606938044258990275541962092341162602522202993782792835301376 1636695303948070935006594848413799576108321023021532394741645684048066898202337277441635046162952078575443342063780035504608628272942696526664263794688
可以看出,想算多大算多大。 提供了四种进制表示形式。
- 十进制:1010 99 -114514
- 二进制:0b01010 0B10101
- 八进制:0O114514 0o1717610
- 十六进制:0x114514 0X1f1fe10
3.1.2 浮点数类型¶
- 与数学中实数概念一致。
- 取值范围和小数精度都存在限制,但是常规计算可以忽略。
- 浮点数运算存在不确定尾数。这不是bug。
In [7]:
print(0.1+0.3)
print(0.1+0.2)
print(0.1+0.2==0.3)
print(round(0.1+0.2,1)==0.3)
0.4 0.30000000000000004 False True
53位二进制表示一个浮点数,由于二进制和十进制的差距,不是一一对应,所以会造成这种问题。 为解决此问题,可以使用round()函数。
- round(x,d):对x四舍五入,截取d的位数。就是说保留几位小数?在这个基础上四舍五入。
- 浮点数运算经常用round来辅助。不确定尾数经常发生在pow(10,-16)左右,因此round十分有效。
可以使用科学计数法来表示浮点数。
- \<a>e\<b> 或者 \<a>E\<b> 表示a*pow(10,b)
- 4.3e-3 表示 0.0043
- 9.6E5表示960000.0
3.1.3 复数类型¶
- pow(j,2) = -1
- a+bj就是复数。a是实部,b是虚部。
In [8]:
z = 1.23e-4 + 5.6e+89j
print(z)
print(z.real) # 获得实部
print(z.imag) # 获得虚部
(0.000123+5.6e+89j) 0.000123 5.6e+89
3.1.4 数值运算操作符¶
- x+y 加
- x-y 减
- x*y 乘
- x/y 除,返回的结果是浮点数
- x//y 整数除,返回的结果是整数 10//3=3
- +x x本身
- -y y的相反数
- x%y 取余数
- x**y 幂运算(y是小数的话开方)
In [11]:
x = 10//3
y = 2**10
z = -12
a = -z
b = +x
c = 10**0.5
d = pow(10,0.5) # pow和**相同
print(x,y,z,a,b,c,d)
3 1024 -12 12 3 3.1622776601683795 3.1622776601683795
- x+=y x-=y x*=y x/=y x//=y x%=y x**=y
- 二元操作符,结果给x
In [12]:
x = 3.1415
x**=3
print(x)
x = 3.1415
x=x**3
print(x)
31.003533398375005 31.003533398375005
- 不同的类型之间可以互相运算,生成结果作为"最宽"的类型
- 整数➡️浮点数➡️复数
In [13]:
print(123+4.0)
127.0
3.1.5 数值运算函数¶
- abs(x) 绝对值
- divmod(x,y) 结果为(商,余数)
- pow(x,y[,z]) (x**y)%z
In [14]:
pow(3,pow(3,99),10000)
# pow(3,pow(3,99)) 很难算出来
Out[14]:
4587
- round(x[,d]) 四舍五入,d默认为0,取整
- max(a,b,...) 最大值
- min(a,b,...) 最小值
类型转换相关的函数:
- int(x) 把括号里的东西弄成整数,无论浮点数、字符串
- float(x) 把括号里的东西弄成浮点数,无论整数、字符串
- complex(x) 变成复数
3.2 代码实现1.01**365和0.99**365¶
In [2]:
# 1 一年365天,每天进步千分之一、退步千分之一。
dayup = pow(1.001,365)
daydown = pow(0.999,365)
print("向上:{:.2f}\n向下:{:.2f}".format(dayup,daydown))
# 2 千分之五呢?百分之一呢?其他呢?
dayfactor = 0.005
dayup = pow(1+dayfactor,365)
daydown = pow(1-dayfactor,365)
print("每天进步{:.3f}可以得到:{:.3f}\n每天退步{:.3f}可以得到:{:.3f}".format(dayfactor,dayup,dayfactor,daydown))
dayfactor = 0.01
dayup = pow(1+dayfactor,365)
daydown = pow(1-dayfactor,365)
print("每天进步{:.2f}可以得到:{:.3f}\n每天退步{:.3f}可以得到:{:.3f}".format(dayfactor,dayup,dayfactor,daydown))
# 3 工作日的力量
# 一年365天,每周2休息日,退步1%。
# 数学思维->计算思维
value = 1
factor_up = 0.01
factor_down = 0.01
for day in range(365):
if day%7 in [0,6]: #周末
value *= (1-factor_down)
else:
value *= (1+factor_up)
print('工作日的力量:{:.2f}'.format(value))
# 4 工作日的努力
# 在工作日,要努力到什么水平,才能和每天1%达到一样的成绩?
# 自己写个函数
def weekday_method(factor_up,factor_down):
value = 1
for day in range(365):
if day%7 in [0,6]:
value *= (1-factor_down)
else:
value *= (1+factor_up)
return value
factor_up = 0.01
factor_down = 0.01
while weekday_method(factor_up,factor_down) < 37.78:
factor_up+=0.001
print('所需的努力参数是:{:.3f}'.format(factor_up))
向上:1.44 向下:0.69 每天进步0.005可以得到:6.175 每天退步0.005可以得到:0.160 每天进步0.01可以得到:37.783 每天退步0.010可以得到:0.026 工作日的力量:4.63 所需的努力参数是:0.019
抽象和自动化是重要的思维。 上面的代码涉及到了while循环、函数、分支等内容。
3.3 字符串类型和操作¶
3.3.1 字符串类型的表示¶
在第一章的时候曾经学习过:
- 字符串:
- 用单引号或者双引号来表达,都一样
- 由0个或多个字符组成的有序序列
- 可以用顺序去做索引,从0开始计数
- 字符串的索引和切片
- 索引:返回单个字符 <字符串>[N]
- TempStr[0]
- "请输入字符串"[2] 表达'入'
- 切片:返回一个子串 <字符串>[M:N] 从M到N-1!
- TempStr[0:-1] 从0开始到-2,即不包含最后一个字符,去掉最后一个字符
- "请输入字符串"[2:4] 表达"入字",但不包含"字" 现在要拓展一下,更加高级的知识:
- 索引:返回单个字符 <字符串>[N]
- 由单引号或者双引号表示的是单行字符串
- 三单引号或者三双引号表示多行字符串
In [ ]:
'''你好,
今晚"'月色'真美"。'''
并不是说三单引号真的能成为注释,而是三单引号可以起到这样的作用。 Python一个人性化的一点是尽可能写的时候舒服点
In [ ]:
'这里面有个双引号"'
"这里面有个单引号'"
- 字符串切片的高级用法
- [M:N:K]表示根据步长来进行切片。
- M可以缺失,表示从开头
- N可以缺失,表示到结尾
- 高级用法:
- 逆序字符串[::-1]
- K为负,表示从后往前输出
In [5]:
test1 = '〇一二三四五六七八九十'
print(test1[:3]) #从开头到第3序号(不含3)
print(test1[1:8:2]) #从1号到8(不含8),间隔2
print(test1[::-1])
〇一二 一三五七 十九八七六五四三二一〇
In [6]:
#输入3
weekStr = "星期一星期二星期三星期四星期五星期六星期日"
weekNum = eval(input("请输入您需要星期几?(数字1-7)"))
weekPos = (weekNum-1)*3
print(weekStr[weekPos:weekPos+3])
星期三
In [7]:
#输入3
weekStr = "一二三四五六七日"
weekNum = eval(input("请输入您需要星期几?(数字1-7)"))
weekPos = (weekNum-1)
print("星期"+weekStr[weekPos])
星期三
3.3.3 字符串处理函数¶
- len(x) 返回字符串长度
- 不论汉字、数字、英文、emoji,都是1
- str(x) 把x变成字符串
- 这与eval恰好是相反的
- hex(x) oct(x) 整数x的十六进制或者八进制小写字符串
- chr(u) unicode编码➡️字符
- ord(x) 字符x➡️unicode编码
- 所有python字符串都是unicode编码
In [11]:
print(len("😅"))
print(str([1,2]))
print("1+1=2" + chr(10004))
print(str(ord("😅")))
for i in range(12):
print(chr(9800+i), end="") #中间没有间隔符号
1 [1, 2] 1+1=2✔ 128517 ♈♉♊♋♌♍♎♏♐♑♒♓
3.3.4 字符串处理方法¶
- 方法:字符串所提供的函数,即字符串对象的函数
- str.lower() str.upper() 返回字符的副本,全部大写/小写
- str.split(sep=None) 返回一个列表,str根据sep进行分隔
- str.count(sub) 返回sub子串在str中出现的次数
- str.replace(old,new) 返回str的副本,所有old子串被替换为new
- str.center(width[,fillchar]) 返回副本,居中str,并使用fillchar填充
- str.strip(chars) 返回副本,去除左、右的在chars中出现的所有字符
- str.join(iter) 在iter中,除了最后一个字符,每个字符后面都加一个str。常用于分隔字符串。
In [18]:
str = "A,B,C,OLG"
print(str.split(','))
str = "ababa"
print(str.count('aba'))
str = "十是十,四是四,十四是十四,四十是四十"
print(str.replace('四','4'))
print(str.center(50,'*'))
print(str) # 注意这些操作都不会改变str本身
str = '= python ='
print(str.strip(' =np'))
str = ' and '
print(str.join("一二三四五"))
['A', 'B', 'C', 'OLG'] 1 十是十,4是4,十4是十4,4十是4十 ***************十是十,四是四,十四是十四,四十是四十**************** 十是十,四是四,十四是十四,四十是四十 ytho 一 and 二 and 三 and 四 and 五
3.3.5 字符串类型的格式化¶
就是类似于C语言的printf那些东西。
- 字符串.format()
- str.format(逗号分隔的参数)
- 槽:{}
- 默认按照0,1,2,...编号
- format中参数的顺序也是一致的
- 也可以给槽手动编号,表示对应第几个参数
In [23]:
str = "{}:计算机{}的CPU占用率为{}%".format("2022-02-12","MacBook Pro 18,3",8)
print(str)
str = "{1}是一门{0},{1}很好用。".format("编程语言","Python")
print(str)
2022-02-12:计算机MacBook Pro 18,3的CPU占用率为8% Python是一门编程语言,Python很好用。
- 槽内部进行格式控制
- {<参数序号>:<格式控制标记>}
- 一共有6个格式控制标记
- 填充、对齐和宽度
- 给输出宽度、对齐方式、多了的怎么填充
- 冒号后,第一个字符是填充内容
- 第二个字符 < 左对齐 ^ 居中对齐 > 右对齐
- 之后的数字表示宽度
In [30]:
str = "{0:=^30}".format("python")
print(str)
str = "{0:=>20}".format("python")
print(str)
str = "{0:=<20}".format("python")
print(str)
============python============ ==============python python==============
- 千位分隔符、精度、类型
- ,表示数字的千位分隔符
- .精度 浮点数小数精度或者字符串最长输出长度
- 类型
- 整数类型b c d o x X
- 分别是二进制、unicode字符、十进制、八进制、小写/大写十六进制
- 浮点数类型 e E f %
- 分别是小写/大写科学计数法、普通浮点数、百分数
In [33]:
str = "{0:=^20,.6f}".format(114514.1919810)
print(str)
str = "{0:b},{0:c},{0:d},{0:o},{0:x},{0:X}".format(425)
print(str)
str = "{0:e},{0:E},{0:f},{0:%}".format(1.14514)
print(str)
===114,514.191981=== 110101001,Ʃ,425,651,1a9,1A9 1.145140e+00,1.145140E+00,1.145140,114.514000%
In [37]:
import time
print(time.time())
print(time.ctime())
print(time.gmtime())
1644638449.641355 Sat Feb 12 12:00:49 2022 time.struct_time(tm_year=2022, tm_mon=2, tm_mday=12, tm_hour=4, tm_min=0, tm_sec=49, tm_wday=5, tm_yday=43, tm_isdst=0)
In [38]:
t = time.gmtime()
print(time.strftime("%Y-%m-%d %H:%M:%S",t))
2022-02-12 04:00:52
看看控制符:
- %Y 年份 0000-9999
- %m 月份 01-12
- %B 英文月份全称,如September
- %b 英文月份简称,如Sep
- %d 日期 01-31
- %A 星期全称,如Monday
- %a 星期简称,如Mon
- %H 24小时制的小时
- %I 12小时制的小时
- %p 上午/下午,AM/PM
- %M 分钟,与%m月份区别开
- %S 秒钟
我们也可以通过strptime()通过时间字符串构造成一个时间变量。
- strptime(时间字符串,模板字符串)
- str 时间字符串
- tpl 模板字符串
In [39]:
timeStr = "2022-02-12 04:00:52"
print(time.strptime(timeStr,"%Y-%m-%d %H:%M:%S"))
time.struct_time(tm_year=2022, tm_mon=2, tm_mday=12, tm_hour=4, tm_min=0, tm_sec=52, tm_wday=5, tm_yday=43, tm_isdst=-1)
In [43]:
start = time.perf_counter()
print(start)
for i in range(1919810):
;
end = time.perf_counter()
print(end)
print(end-start)
192355.968274708 192356.017365416 0.04909070799476467
- sleep(s)
- s单位是秒,让程序拟休眠的时间
- time.sleep(3.3) 让程序休眠3.3秒
In [44]:
start = time.perf_counter()
time.sleep(5)
end = time.perf_counter()
print(end-start)
5.00568583299173
In [48]:
scale = 10
print("{0:=^20}".format("执行开始"))
for i in range(scale+1): #从0到10,11次循环
a = '*' * i
b = '.' * (scale-i)
c = (i/scale)*100
print("{:^3.0f}%[{}->{}]".format(c,a,b))
time.sleep(0.2)
print("{0:=^20}".format("执行结束"))
========执行开始======== 0 %[->..........] 10 %[*->.........] 20 %[**->........] 30 %[***->.......] 40 %[****->......] 50 %[*****->.....] 60 %[******->....] 70 %[*******->...] 80 %[********->..] 90 %[*********->.] 100%[**********->] ========执行结束========
3.5.2 实现单行动态刷新¶
- 即用之后的字符覆盖原来的字符
- 需要不换行(end="")、回退(\r)
In [51]:
#从0到100的动态刷新
for i in range(101):
print("\r{:3}%".format(i),end="")
time.sleep(0.1)
100%
3.5.3 完整效果¶
In [60]:
scale = 50 # 迭代50次
width = 15 # 20+->,共22
print("执行开始".center(scale//2,"*"))
start = time.perf_counter() # 实现计时效果
for i in range(scale+1):
progress = (i / scale)
a = '▶️' * (round(width*progress))
b = '⏺' * (width - round(width*progress))
end = time.perf_counter()
duration = end - start
print("\r{:.3%} [{}->{}] duration:{:.3f}".format(progress,a,b,duration),end="")
time.sleep(0.2)
print("\n执行完毕".center(scale//2,"*"))
***********执行开始********** 100.000% [▶️▶️▶️▶️▶️▶️▶️▶️▶️▶️▶️▶️▶️▶️▶️->] duration:10.214********** 执行完毕**********
应该在长时间运行的程序中加入进度条,这也能够提升人们的体验。 当然,这涉及到一些有些有趣的心理学问题,比如前面增长的很快,后面很慢,这样就不太符合人的直观感受。 有相关的研究,开始展示的慢一些,后面越来越快,这样更符合人们的心理感受。
沙发(doge
捕捉到你了