[python学习笔记]Python语言程序设计(北理工 嵩天)
赶时髦,python这么火,学习一哈
1.python基本语法元素
1.1 程序设计基本方法
计算机发展历史上最重要的预测法则 摩尔定律:单位面积集成电路上可容纳晶体管数量约2年翻倍 cpu/gpu、内存、硬盘、电子产品价格等都遵循此定律
50年来计算机是唯一一个指数发展的领域
源代码、目标代码(机器代码)
编译、解释
静态语言、脚本语言
静态语言编译器一次性生成目标代码,优化更冲份,程序运行速度更快
脚本语言 执行程序时需要源代码,维护更灵活
程序的基本设计方法ipo
i:input 文件输入、网络输入、控制台输入、交互界面输入、内部参数输入
p:process 处理
o:output 控制台输出、图形输出、文件输出、网络输出、操作系统内部输出
6个步骤:
-分析问题:分析问题的计算部分,想清楚
-划分边界:划分问题的功能边界,规划ipo
-设计算法:设计问题的求解算法,关注算法
-编程
-调试测试
-升级维护
3个精简步骤:确定ipo、编程、调试运行
计算思维(编程体现了一种抽象交互关系、自动化执行的思维模式)、逻辑思维、实证思维
1.2 python开发环境配置
python 蟒蛇
psf 拥有者,开放、开源精神
guido van rossum创立
2002年 2.x
2008年 3.x
python3不兼容python2
交互式、文件式
linux自带python2和python3,无需安装,不过没有pip,要安装apt install python3-pip
trouble shooting:python3中import turtle modulenotfounderror: no module named 'tkinter'报错
apt install python3-tk
apt install tk-dev或yum install tk-devel
然后import turtle不报错了
test一下
test1
test2
test3
1.3 实例1:温度转换
实例1:温度转换
需求:摄氏度与华氏度相互转换
#tempconvert.py tempstr = input("请输入带有符号的温度值: ") if tempstr[-1] in ['f', 'f']: c = (eval(tempstr[0:-1]) - 32)/1.8 print("转换后的温度是{:.2f}c".format(c)) elif tempstr[-1] in ['c', 'c']: f = 1.8*eval(tempstr[0:-1]) + 32 print("转换后的温度是{:.2f}f".format(f)) else: print("输入格式错误")
1.4 python程序语法元素分析
程序的格式框架:
代码高亮 是辅助
缩进是语法要求 一般4个空格或者1个tab 表达代码间包含和层次关系的唯一手段
注释:单行注释 # 多行注释 ''' '''
命名:给变量关联标识符的过程
命名大小写敏感、首字符不能是数字、不与保留字相同
保留字:被编程语言内部定义并保留使用的标识符 也大小写敏感 33个
数据类型
字符串
用‘’或“”
正向递增序号、反向递减序号 正向0开始编号
索引: 可以使用[m]索引其中单个字符
切片:可以使用[m:n]返回其中一段子串,从第m到第n-1个字符
数字类型:整数、浮点数
列表:表示0到多个数据组成的有序序列,采用,分隔各元素,使用in判断一个元素是否在列表中
= 赋值主语句
分支语句if elif else构成
eval 评估函数 去除参数最外侧引号并执行余下语句的函数
垂直输出hello world
for i in "hello world":
print(i)
输出
x = input()
print(eval(x)**0,eval(x)**1,eval(x)**2,eval(x)**3,eval(x)**4,eval(x)**5)
2. python基本图形绘制
2.1 深入理解python语言
计算机演进过程:
1946-1981 计算机系统结构时代 计算能力问题 1981年个人pc诞生
1981-2008 网络和视窗时代 交互问题 2008 android诞生 标志pc转向移动
2008-2016 复杂信息系统时代 数据问题 2016年alpha go打败人类
2017- 人工智能时代 人类的问题
新计算时代 过度到人工智能时代的中间时代
编程语言的初心
不完全统计600多中语言 常用的也就那么20来种
python已经在tiobe排行超过c++跃居第三
python语言是通用语言、脚本语言、开源语言、跨平台语言、多模型语言
--强制可读性
--较少的底层语法元素
--多种编程方式
--支持中文字符
--c代码量的10% 语法简洁 *10
--13万第三方库 生态高产 *10
--快速增长的计算生态 每年2万
--避免重复造*
--开放共享
--跨操作系统平台
人生苦短 我学python
--c/c++:c归c python归python
--java:针对特定开发和岗位需求
--html/css/js:不可替代的前端技术,全栈能力
-r/go/matlab等:特定领域
python是最高产的程序设计语言
--掌握抽象并求解计算问题综合能力的语言
-了解产业界解决复杂计算问题方法的语言
-享受利用编程将创新变为实现乐趣的语言
工具决定思维:关注工具变革的力量!
python具有最庞大的生态库,是唯一的超级语言,前进步伐不可阻挡
2.2 实例2:python蟒蛇绘制
#pythondraw.py import turtle turtle.setup(650, 350, 200, 200) turtle.penup() turtle.fd(-250) turtle.pendown() turtle.pensize(25) turtle.pencolor("purple") turtle.seth(-40) for i in range(4): turtle.circle(40, 80) turtle.circle(-40, 80) turtle.circle(40, 80/2) turtle.fd(40) turtle.circle(16, 180) turtle.fd(40 * 2/3) turtle.done()
2.3 模块1: turtle库的使用
turtle库基本介绍
import 保留字 引入turtle绘图库 海龟绘图体系
turtle库是turtle绘图体系的python实现 1969年诞生,主要用于程序设计入门 python的标准库之一 入门级的图形绘制函数库
python计算生态=标准库+第三方库
库library,包package,模块module ,统称模块
有一只海龟,其实在窗体正中心,在画布上游走,走过的轨迹绘制的图形,海龟由程序控制,可以变换颜色宽度
turtle绘图窗体布局
turtle的一个画布空间 最小单位是像素
屏幕坐标系:屏幕左上角为0 0
turtle.setup(width,height,startx,starty)后两个可选 默认屏幕* 并不是必须的 用来设置窗体大小和窗体左上角与屏幕左上角的相对位置
turtle空间坐标系:
绝对坐标 海龟在屏幕* 记为(0,0)坐标原点 turtle.goto(x,y)
海龟坐标 以海归的视角turtle.fd(d),turtle.bk(d),turtle.circle(r,angle) 左侧r为止为中心行走angle角度的弧线
turtle角度坐标体系
绝对角度 改变海龟前进方向 turtle.seth(angle)
海龟角度 turtle.left(angle),turtle.right(angle)
rgb色彩体系 0-255整数或 0-1 的小数
默认采用小数制,可切换为整数制 turtle.colormode(mode) mode为1.0或255
2.4 turtle语法元素分析
库引用
扩充python程序功能的方式 使用import保留字完成,采用<a>.<b>()的编码风格
from turtle import* 缺点 函数重名 适用于短的程序
from turtle import函数名
可以as保留字起别名 import turtle as t --推荐使用
画笔控制函数
画笔操作后一直有效,一般成对出现
-turtle.penup() 别名turtle.pu() 抬起画笔,海龟在飞行
-turtle.pendown() 别名turtle.pd() 落下画笔,海龟在爬行
画笔设置后一直有效,直到下次设置
-turtle.pensize(width) 别名turtle.width(width) 画笔宽度,海龟腰围
-turtle.pencolor(color) color为颜色字符串或rgb值 画笔颜色,海龟在涂装
-颜色字符串 turtle.pencolor("purple")
-rgb小数 turtle.pencolor(0.63,0.13,0.94)
-rgb元组值 turtle.pencolor((0.63,0.13,0.94))
运动控制函数
控制海龟行进:走直线&走曲线
-turtle.forward(d) 别名 turtle.fd(d) 向前行进,海龟走直线 d可以为负数
-turtle.circle(r,extent=none) 根据半径r绘制extent角度的弧线 r默认圆心在海龟左侧r距离的位置 -extent绘制角度,默认是360度
方向控制函数
turtle.setheading() 别名turtle.seth() 控制海龟面对方向:绝对角度 海龟角度
turtle.left() turtle.right()
循环语句
for in 保留字
range() 产生循环计算序列 range(n) range(m:n) 0到n-1 m到n-1
turtle.done() 运行结束 不退出 需要手工退出 去掉就自动退出了
3. 基本数据类型
3.1 数字类型及其操作
整数类型:可正可负 取值无限 pow(x,y) x的y次方
4种进制表示:10进制、二进制0b或0b开头 0b010、8进制0o或0o、16进制0x或0x
浮点型 10的308次方 精度达到:10的-16次方小数 即53位二进制 与数学中实数一致
不确定尾数 (浮点数运算)不是bug 53位二进制表示浮点数的小数部分 约10的-16次方 计算机中的二进制和十进制不完全对等
二进制表示小数,可以无限接近,但不完全相同
0.1+0.2 结果接近0.3
0.1+0.2 == 0.3 false 用round(x,d)处理不确定尾数 不确定位数一般发生在10的-16次方左右
科学计数法 e或e作为幂的符号,10为基数 <a>e<b> 4.3e-3
复数类型 z.real z.imag 获得实部和虚部
数值运算操作符
x+y x-y x*y x/y x//y +x -y x%y x**y ps:x/y 是浮点数 别的语言中不是这样
二元操作符有对应的增强赋值操作符
x op =y x+=y x-=y x*=y x/=y x//=y x%=y x**=y
类型间可以混合运算 结果生成为“最宽”的类型 隐式转换 整数->浮点数->复数 如123+4.0=127.0
数值运算函数
abs(x) 绝对值
divmod(x,y) 商余 divmod(10,3) 结果是二元数(3,1)
pow(x,y[,z]) 幂余
round(x[,d]) 四舍五入
max(x1,x2,..)
min(x1,x2,..)
int(x) 显示类型转换, 变为整数,舍弃小数
float(x) 转浮点数
complex(x) 转复数
3.2 实例3:天天向上的力量
问题分析:持续的价值 一年365天每天进步1%,累计进步多少?相反,每天退步1%,累计剩下多少?如果三天打渔二天晒网呢?
print("向上{:.2f},向下{:.2f}".format(pow(1.001,365),pow(0.999,365))) 结果: 向上1.44,向下0.69
如果是0.5% 1%呢
#daydayup1.py factor=0.005 print("向上{:.2f},向下{:.2f}".format(pow(1+factor,365),pow(1-factor,365)))
结果:
0.5% :向上6.17,向下0.16
1%:向上37.78,向下0.03
如果是工作日的力量?工作日进步1%,休息日退步1%
#daydayup.py dayup=1.0 factor=0.01 for i in range(365): if i % 7 in [6,0]: dayup *= 1-factor else: dayup *= 1+factor print("{:.2f}".format(dayup))
结果:4.63
工作日的努力要达到多少才能和每天努力1%一样?
#daydayup.py def dayup(factor): dayup=1.0 for i in range(365): if i % 7 in [6,0]: dayup *= 1-0.01 else: dayup *= 1+factor return dayup; dayfactor = 0.01 while dayup(dayfactor) < 37.78: dayfactor += 0.001 print("工作日的努力参数是:{:.3f} ".format(dayfactor))
结果是:1.9%
3.3 字符串类型及操作
四种字符串表示方法:
由一对单引号或双引号表示单行字符串
由一对三引号或三双引号表示多行字符串
三单引号表示字符串,程序啥都不执行,相当于注释,python实际没有真正提供多行注释
[m:n:k]根据步长对字符串切片 m和n均可以缺失,表示至开头或至结尾
[::-1]倒序
转义符\ \b 回退 \n 换行 \r 回车光标移动到行首
字符串操作符
x+y 连接两个字符串
n*x或x*n 复制n次字符串x
x in s
字符串处理函数
len(x) 字符串长度 中英文长度都是1
str(x) 强制类型转换为字符串 和eval相反操作
hex(x) 整数x转变为8进制形式
oct(x) 整数x转变为16进制形式
chr(x) 将unicode编码返回其字符形式
ord(x) 上面的反操作
unicode编码 统一字符编码 从0到1114111(0x10ffff) python字符串每个字符都是unicode编码
字符串处理方法
<a>.<b> 形式 面向对象的术语 表示对象的动作
8个字符串处理方法
.lower() .upper() 大小写转换
.split(sep=none) 字符串分割,返回一个列表 例:"a,b,c".split(',')结果是['a', 'b', 'c']
.count(sub) 字符串sub在其中出现次数
.replace(old,new) 字符串替换
.center(width[,fillchar]) 字符串格式处理,字符串居中 例: 'python'.center(30,'=') 结果'============python============'
.strip(chars) 去除字符换两边字符 如:'= python= '.strip(' =np')结果'ytho'
.join(iter) 填充字符 如:','.join('12345')结果'1,2,3,4,5'
字符串类型的格式化
格式化是对字符串进行格式化表达的方式
.format方法 用法:<模板字符串>.format(<逗号分隔的参数>)
槽 相当于占位信息符,只在字符串中有用
format方法的格式控制 6种格式控制标记
分为2组
前三个参数是一组 默认填充空格左对齐
如: "{:=^20}".format("python") 结果: '=======python======='
如: "{0:,.2f}".format(12345.6789) 结果 '12,345.68'
如:"{0:b} {0:c} {0:d} {0:o} {0:x} {0:x}".format(425) 结果'110101001 ʃ 425 651 1a9 1a9'
如: "{0:e} {0:e}{0:f} {0:%}".format(3.14) 结果 '3.140000e+00 3.140000e+003.140000 314.000000%'
3.4 模块2:time库的使用
time库是python中处理时间的标准库
时间获取
time() 获取当前时间戳,即计算机系统内部时间值,浮点数 1970年1月1日0点0分开始到当前系统以秒为单位的浮点数 如:1537763974.4934046
ctime() 获取当前时间,返回字符串,人类易读 如:'mon sep 24 12:41:59 2018'
gmtime() 获取当前时间,struct_time格式,计算机易处理的格式
如:time.struct_time(tm_year=2018, tm_mon=9, tm_mday=24, tm_hour=4, tm_min=42, tm_sec=52, tm_wday=0, tm_yday=267, tm_isdst=0)
时间格式化
strftime()
格式化字符串
striptime()
程序计时
perf_counter()
sleep()
3.5 实例4:文本进度条
问题分析:采用字符串方式打印可以动态变化的文本进度条 能在一行中逐渐变化
刷新的本质:用后打印的字符覆盖之前的字符
print() 默认加换行 print( ,end=””)不换行 \r退格到行首
idle不是主要的运行环境 所以\r功能在idle屏蔽了 用shell执行
#textprobar.py import time scale = 50 print("执行开始".center(scale//2, "-")) start = time.perf_counter() for i in range(scale+1): a = '*' * i b = '.' * (scale - i) c = (i/scale)*100 dur = time.perf_counter() - start print("\r{:^3.0f}%[{}->{}]{:.2f}s".format(c,a,b,dur),end='') time.sleep(0.1) print("\n"+"执行结束".center(scale//2,'-'))
4.程序的控制结构
4.1 分支结构
单分支结构
if <条件>:
<程序1>
二分支结构
if <条件1>:
<程序1>
else:
<程序2>
紧凑形式:适用于简单表达式的二分支结构
<表达式1> if <条件> else <表达式2>
如:
guess = eval(input())
print(“猜{}了”.format(“对”if guess == 99 else ”错”))
多分支结构
if <条件1>:
<程序2>
elif <条件2>:
<程序3
…
else:
<程序n>
条件判断> >= < <= == !=
条件组合x and y x or y not x
异常处理
try:
程序1
except [nameerror]:
程序2
try:
程序1
except:
程序2
else:
程序3
finally:
程序4
4.2 实例5:身体质量指数bmi
问题分析:bmi是身体肥胖程度的刻画(body mass index) bmi=体重(kg)/身高的平方(m),接收用户信息判断身体肥胖程度
#calbmi.py height,weight=eval(input("输入身高体重用逗号隔开")) bmi = weight/pow(height,2) print("bmi数值:{:.2f}".format(bmi)) who,nat = "","" if bmi < 18.5: who,nat="偏瘦","偏瘦" elif 18.5 <= bmi < 24: who,nat="正常","正常" elif 24 <= bmi < 25: who,nat="正常","偏胖" elif 25 <= bmi < 28: who,nat="偏胖","偏胖" elif 28 <= bmi < 30: who,nat="肥胖","偏胖" else: who,nat="肥胖","肥胖" print("bmi指标为 国内{},国际{}".format(who,nat))
4.3 循环结构
for 遍历循环
for <循环变量> in <遍历结构>:
<语句块>
记数循环
for i in range(5):
print(i)
for i in range(m:n:k):
print(i)
字符串遍历循环
for c in s:
<语句块>
for c in "python123":
print(c)
列表遍历循环ls是列表
for item in ls:
<语句块>
for item in [123,"py",456]:
print(item,end=',')
文件遍历循环 fi是文件标识符
for line in fi:
<语句块>
while 无限循环
while <条件>:
<语句>
循环控制保留字break continue
循环扩展:两种循环后面都可以加else分支 else为没有被break退出是执行的,作为正常运行的奖励
4.4 模块3:random库使用
random库是使用随机数的python标准库
计算机没法产生真正的随机数,但是可以使用梅森旋转算法产生伪随机数
使用 import random
random库包括2类函数,常用共8个
基本随机数函数:seed(),random()
括展随机数函数:randint(),getrandbits(),uniform(),randrange(),choice(),shuffle()
随机数种子
seed(a=none) 初始化给定的随机数种子,默认为系统当前时间,例:random.seed(10) #产生种子10对应的序列 0.5714025946899135 0.4288890546751146 ..
random() 生成一个[0.0,1.0)之间的随机小数,例:random.random()
为什么要使用随机数种子呢,因为可以使用相同的随机数种子复现程序的执行情况
randint(a,b) 生成一个[a,b]之间的整数,例:random.randint(10,100)
randrange(m,n[,k]) 生成一个[m,n)之间以k为步长的随机整数,例:random.random(10,100,10)
getrandbits(k) 生成一个k比特长的随机整数
uniform(a,b) 生成一个[a,b]之间的随机小数
choice(seq) 从序列中随机选择一个元素,例:random.choice([1,2,3,4,5,6])
shuffle(seq) 将序列中元素随机排序,返回打乱后的序列,例:s=[1,2,3,4];random.shuffle(s);print(s)
4.4 实例6:圆周率计算
#calpi.py from random import random from time import perf_counter darts = 1000*1000 hits = 0.0 start = perf_counter() for i in range(1,darts+1): x,y = random(),random() dist = pow(x**2 + y**2,0.5) if dist <=1.0: hits = hits + 1 pi = 4 * (hits/darts) print("圆周率是:{}".format(pi)) print("运行时间是:{:.5f}s".format(perf_counter()-start))
蒙特卡罗方法 工程方法
数学思维
计算思维
time库perf_counter来关注程序性能
据统计,程序80%的时间消耗在不到10%的代码上 有点儿类似28法则
关注循环
5.函数和代码复用
5.1 函数的定义与使用
函数定义
函数是一段具有特定功能可复用的语句
df <函数名>(参数):
<函数体>
return <返回值>
其中参数可以是0个到多个,是占位符
函数不经过调用是不会执行的
函数就是ipo的实现
函数也是一段完整代码的封装
函数的参数传递
可选参数传递:可以为参数指定默认值,变为可选参数,可选参数要放在非可选参数之后
可变参数传递:不确定参数有多少个
参数传递的两个方式
默认是按照位置,可以按照名称方式传递
函数的返回值
return可以返回0个或多个结果
函数可以有返回值也可以没有
可以有return 也可以没有
返回多个值的时候是返回元组类型 用() 元素用逗号分隔
局部变量与全局变量
函数外边的是全局变量,里面是局部变量
局部变量是函数内部的占位符,可能与全局变量重名单不相同
函数运行结束后局部变量被释放
规则1:局部变量与全局变量是不同变量
可以使用global保留字在函数内部使用全局变量
规则2:局部变量如果是组合数据类型且未被创建,等同于全局变量 组合数据类型实际是指针的原因
lambda函数
lambda函数返回函数名作为结果
lambda函数是一种匿名函数,没有名字的函数
lambda函数用于定义一种简单的能够在一行内表示的函数
是一种函数的紧凑表达形式
<函数名> = lambda <参数>:<表达式>
f = lambda x,y : x + y
f(10,15)
谨慎使用lambda函数
用于特定的方法的参数
一般就算是1行代码,也建议用def方式定义
5.2 实例7:七段数码管绘制
问题分析:用turtle绘制数码管样式的时间
from turtle import* from time import* def drawgap(): penup() fd(5) def drawline(draw): #绘制单段数码管 drawgap() pendown() if draw else penup() fd(40) drawgap() right(90) def drawdigit(digit): drawline(true) if digit in [2,3,4,5,6,8,9] else drawline(false) drawline(true) if digit in [0,1,3,4,5,6,7,8,9] else drawline(false) drawline(true) if digit in [0,2,3,5,6,8,9] else drawline(false) drawline(true) if digit in [0,2,6,8] else drawline(false) left(90) drawline(true) if digit in [0,4,5,6,8,9] else drawline(false) drawline(true) if digit in [0,2,3,5,6,7,8,9] else drawline(false) drawline(true) if digit in [0,1,2,3,4,7,8,9] else drawline(false) left(180) penup() fd(20) def drawdate(date):#date为日期,格式约定为 '%y-%m=%d+' pencolor("red") for i in date: if i == '-': write('年',font=("arial",18,"normal")) pencolor("green") fd(40) elif i == '=': write('月',font=("arial",18,"normal")) pencolor("blue") fd(40) elif i == '+': write('日',font=("arial",18,"normal")) else: drawdigit(eval(i)) def main(): setup(800,350,200,200) penup() fd(-300) pensize(5) drawdate(strftime('%y-%m=%d+',gmtime())) hideturtle() done() main()
结果:
5.3 代码复用与函数递归
代码复用
代码抽象化:使用函数等方法对代码赋予更高级别的定义
函数和对象是代码复用的2中主要形式
函数是在代码层面建立了初步抽象
对象有属性和方法,是更高级别的抽象
封装
模块化设计
分而治之:
通过函数或对象封装将程序划分为模块与模块间的表达
主程序、子程序与子程序之间的关系
一般将子程序看作模块,主程序看作模块与模块间的关系
是一种分而治之、分层抽象、体系化的设计思想
紧耦合:两个部分之间交流很多,无法独立存在
松耦合:两个部分之间交流很少,可以独立存在,有各自清晰简单的接口
模块化设计基本思路和原则:模块内部紧耦合,模块之间松耦合
函数递归:函数定义中调用自身的方式
两个关键特征
链条:计算过程存在递归链条
基例:存在一个或者多个不需要再次递归的基例 递归的最末段
类似数学归纳法,先证明第一个取值命题成立,然后第n个取值命题成立,第n+1取值命题也成立,那么命题成立
递归可以理解为数学归纳法思维在编程中的体现
函数递归的调用
函数+分支语句 :基例和链条分别编写代码
3个小栗子
5.4 模块4:pyinstaller库的使用
是第三方库 需要安装
pip工具
shell中使用使用 pyinstaller –f <文件名.py>
5.5 实例8:科赫雪花小包裹
#kochdraw.py import turtle def koch(size, n): if n == 0: turtle.fd(size) else: for angle in [0, 60, -120, 60]: turtle.left(angle) koch(size/3, n-1) def main(): turtle.setup(600,600) turtle.penup() turtle.goto(-200, 100) turtle.pendown() turtle.pensize(2) level = 3 # 3阶科赫雪花,阶数 koch(400,level) turtle.right(120) koch(400,level) turtle.right(120) koch(400,level) turtle.hideturtle() main()
结果:
6. 组合数据类型
6.1 集合类型及操作
集合是多个元素的无序组合,每个元素唯一,不存在相同元素
集合元素不可更改,不能是可变数据类型,比如列表类型就不能作为元素,整数浮点数复数字符串元组类型等都是不可变数据类型
用{}表示,元素间用逗号分隔
建立集合用{}或者set()
例如:b = set(“pypy123”) 结果{‘1’,’2’,’3’,’p’,’y’}
建立空集合必须用set()
6个集合操作符
s | t 并
s – t 差
s & t 交
s ^ t 补
s <= t、s < t 包含与子集关系
s >= t、s > t
增强操作符
s |= t
s –= t
s &= t
s ^= t
10个集合处理方法
s.add(x) 如果x不在s中,将x元素加入s集合
s.discard(x) 移除s中元素x,如果x不在集合s中,不报错
s.remove(x) 移除s中元素x,如果x不在s中,产生keyerror异常
s.clear() 移除s中所有元素
s.pop() 随机返回s的一个元素,更新s,若s为空产生keyerror异常
s.copy() 返回集合s的一个副本
len(s) 返回个数
x in s 判断s中是否有元素x
x not in s 同上相反
set(x) 将其他类型变量x转变为集合类型
集合类型应用场景
包含关系的比较
数据去重
6.2 序列类型及操作
序列是有先后顺序的一组元素
序列是一维元素向量,元素类型可以不同,类似c语言中的一维数组
元素间由序号引导,通过下标访问序列的特定元素
序列是一个基类类型
一般不直接用序列类型而是使用其衍生类型,比如字符串、元组、列表
序列处理函数与方法
元组类型
元组是一种序列类型,一旦创建就不能被修改
使用()或者tuple()创建,元素间用逗号分隔
可以使用或不适用小括号,比如函数返回多个返回值就是使用没有括号的元组类型,python内部认为是一个值,是一个元组
元组类型继承了序列的所有通用操作
元组类型因为一旦定义不能修改,所以没有特殊操作
列表类型及操作
列表是序列类型的扩展,十分常用
列表是一种序列类型,创建后可以随意修改,长度无限制,元素类型可不同
列表本质是指针,如果通过赋值语句给另外一个变量,那么实际并没有创建一个新列表,可以类似linux的硬链接,[]或者函数list()才是真正创建一个列表,赋值仅仅传递引用
一些例子
一些例子
序列类型应用场景
包含元组列表
元组用于元素不改变的场景,更多用于固定场景 比如函数返回值
列表则更加灵活,是常用的序列类型
最主要作用:表示一组有序数据并进而操作它们
元素遍历 for item in lt
数据保护 利用元组不可修改的特性
6.3 实例9:基本统计值计算
问题分析:给出一组数据,给出概要理解,比如 求和、平均值、方差、中位数…
总个数:len()
求和:for … in
平均值:上2个除
方差:各数据与平均值的平方的和的平均数
中位数:排序,取中间的或者中间2个数平均数
#calstatisticsv1.py def getnum(): #获取用户不定长度的输入 nums = [] inumstr = input("请输入数字(回车退出): ") while inumstr != "": nums.append(eval(inumstr)) inumstr = input("请输入数字(回车退出): ") return nums def mean(numbers): #计算平均值 s = 0.0 for num in numbers: s = s + num return s / len(numbers) def dev(numbers, mean): #计算方差 sdev = 0.0 for num in numbers: sdev = sdev + (num - mean)**2 return pow(sdev / (len(numbers)-1), 0.5) def median(numbers): #计算中位数 sorted(numbers) size = len(numbers) if size % 2 == 0: med = (numbers[size//2-1] + numbers[size//2])/2 else: med = numbers[size//2] return med n = getnum() #主体函数 m = mean(n) print("平均值:{},方差:{:.2},中位数:{}.".format(m, dev(n,m),median(n)))
6.4 字典类型及操作
字典类型的定义
映射 是一种键(索引)和值(数据)的对应
用{}或者dict()创建字典,键值对用:表示 {key:value,key2:value2…}
type()可以检测变量的类型
{}可以用来声明空字典,这就是集合类型中定义空集合不能用{}的原因
一些例子
6.5 模块5:jieba库的使用
优秀的中文分词第三方库
由于中文是连续书写的 需要通过特定手段获得单个词语
jieba库提供3种分词模式,最简单只需要掌握一个函数
通过中文词库方式识别确定汉字之间关联概率 概率大的组成词组,形成分词效果
除了分词,用户也可以添加自定义的词组
三种模式
精确模式:把文本精确的切分开,不存在冗余单词 最常用的分词模式
全模式:把文本中所有可能的词语都扫描出来,存在冗余
搜索引擎模式:更加智能,在精确模式的基础上,对长词再次切分,存在冗余,在某些特定场景下使用
6.6 实例10:文本词频统计
问题分析:一篇文章,出现了哪些词?哪些词最多?
中英文各一个程序:分别是哈姆雷特和三国演义
#calhamletv1.py def gettext(): txt = open("hamlet.txt", "r").read() txt = txt.lower() for ch in '!"#$%&()*+,-./:;<=>?@[\\]^_‘{|}~': txt = txt.replace(ch, " ") #将文本中特殊字符替换为空格 return txt hamlettxt = gettext() words = hamlettxt.split() counts = {} for word in words: counts[word] = counts.get(word,0) + 1 items = list(counts.items()) items.sort(key=lambda x:x[1], reverse=true) for i in range(10): word, count = items[i] print ("{0:<10}{1:>5}".format(word, count))
#calthreekingdomsv2.py import jieba excludes = {"将军","却说","荆州","二人","不可","不能","如此"} txt = open("threekingdoms.txt", "r", encoding='utf-8').read() words = jieba.lcut(txt) counts = {} for word in words: if len(word) == 1: continue elif word == "诸葛亮" or word == "孔明曰": rword = "孔明" elif word == "关公" or word == "云长": rword = "关羽" elif word == "玄德" or word == "玄德曰": rword = "刘备" elif word == "孟德" or word == "丞相": rword = "曹操" else: rword = word counts[rword] = counts.get(rword,0) + 1 for word in excludes: del counts[word] items = list(counts.items()) items.sort(key=lambda x:x[1], reverse=true) for i in range(10): word, count = items[i] print ("{0:<10}{1:>5}".format(word, count))
7. 文件和数据格式化
7.1 文件的使用
文件的类型
文本文件、二进制文件 只是展示方式,本质上都是二进制数据
文本文件:由单一特定编码组成的文件,如utf-8编码 由于存在编码,文本文件也被看为一个长字符串
二级制文件:数据间没有统一字符编码,01组成,比如png avi等文件
文件的打开和关闭
打开->操作->关闭 文件存储状态和占用状态转换
文件的打开
<变量名> = open(<文件名>,<打开模式>)
文件句柄
文件路径和名称,使用相对路径或者绝对路径,同一个路径的话就直接文件名,斜杠\是转移字符使用反斜杠/替换,或者\\
打开模式
<变量名>.close 关闭文件
当程序退出的时候,python也会自动关闭文件
文件内容的读取
<f>.read(size=-1) 读入全部内容,如果给出参数,读入前size长度
<f>.readline(size=-1) 读入一行,如果给了size,读入该行前size长度
<f>.readlines(hint=-1) 读入文件所有行,以每行为元素形成列表,hint参数可选,读入前hint行
遍历全文本
文件的逐行处理
文件写入
<f>.write(s) 向文件写入一个字符串或字节流 如:f.write(“abc”)
<f>.writelines(lines) 将一个元素全为字符串的列表写入文件 如:ls=[‘a’,’b’,’c’],f.writelines(ls)
<f>.seek(offset) 改变当前文件操作指针的位置,offset含义如下:0文件开头,1-当前位置,2-文件结尾
例子:
f = open("2.txt","w+") ls = ['中国', '法国', '美国'] f.writelines(ls) f.seek(0) for line in f: print(line) f.close()
7.2 实例11:自动轨迹绘制
问题分析:根据脚本来绘制图形 不是写代码而是写数据绘制轨迹
#autotracedraw.py import turtle as t t.title('自动轨迹绘制') t.setup(800, 600, 0, 0) t.pencolor("red") t.pensize(5) #数据读取 datals = [] f = open("data.txt") for line in f: line = line.replace("\n","") datals.append(list(map(eval, line.split(",")))) f.close() #自动绘制 for i in range(len(datals)): t.pencolor(datals[i][3],datals[i][4],datals[i][5]) t.fd(datals[i][0]) if datals[i][1]: t.rt(datals[i][2]) else: t.lt(datals[i][2])
自动化思维
将数据和功能分离开来
数据驱动
接口化设计
可以扩展
扩展接口设计,增加更多控制接口
扩展功能设计,增加弧形等更多功能
扩展应用需求,发展自动轨迹绘制到动画绘制
7.3 一维数据的格式化
一维数据:由对等关系的有序或无序数据构成,采用线性方式组织,对应列表、集合、数组等概念
二维数据:由多个一维数据组成,是一维数据的组合形式
多维数据:是一维或二维数据在新唯独上扩展形成,比如中国大学排行榜加入时间维度
高维数据:仅利用最基本的二元关系展示数据间的复杂结构,比如字典类型中的key-value形式
操作周期
一维数据的表示
如果数据间有序,使用列表类型
如果数据间无序,使用集合类型
一维数据的存储
一维数据的处理
类似于一个驱动
7.4 二维数据的格式化和处理
二维列表
两层for循环遍历二维列表
csv:comma-separated values 逗号分隔 国际通用 一般.csv为扩展名
每行一个一维数据,无空行
一般的软件都能生成csv格式文件
如果每个元素缺失,逗号要保留
表头可以作为数据存储,也可以令行存储
如果数据中包含逗号,不同的软件有不同的约定,比如转义符或者其他方式
按行存或者按列存都行,一般索引习惯 ls[row][col] 先行后列,按行存
二维数据的处理
读入处理
7.5 模块6:wordcloud库的使用
词云展示的第三方库
wordcloud库把词云当作一个wordcloud对象
wordcloud.wordcloud()代表一个文本对应的词云
可以根据文本中词语出现的频率等参数绘制词云
绘制词云的形状、尺寸、颜色都可以设定
w = wordcloud.wordcloud()
以wordcloud对象为基础
配置参数、加载文本、输出文件
常规方法
w.generate(txt) 向wordcloud对象w中加载文本txt 如:w.generate(“python and wordcloud”)
w.to_file(filename) 将词云输出为图像文件,.png或.jpg格式 如:w.to_file(“output.png”)
绘制词云的步骤:
setp1:配置对象参数
setp2:加载词云文本
step3:输出词云文件
生成默认400*200的图片
wordcloud干啥了:
a.分隔:以空格为分隔单词
b.统计:单词出现次数并过滤
c.字体:根据统计配置字号
d.布局:颜色环境尺寸
对象参数
width 默认400
height 默认200
min_font_size 最小字号 默认4号
max_font_size 最大字号 根据高度自动调节
font_step 默认1,字体步进间隔
font_path 字体路径,默认none,如:w=wordcloud.wordcloud(font_path=”msyh.ttc”)
max_words 指定词云显示的最大单词数量,默认200 比如词云显示的不那么有力,可以修改这个
stop_words 指定排除单词 如:w=wordcloud.wordcloud(stop_words={“python”})
background_color 指定背景色 默认黑色
默认显示的矩形效果,使用mask参数可以改变
中文的话需要先用jieba库分词,中文不是空格分隔的
7.6 实例12:*工作报告词云
常规矩形词云
#govrptwordcloudv1.py import jieba import wordcloud f = open("新时代中国特色*.txt", "r", encoding="utf-8") t = f.read() f.close() ls = jieba.lcut(t) txt = " ".join(ls) w = wordcloud.wordcloud( \ width = 1000, height = 700,\ background_color = "white", font_path = "msyh.ttc" ) w.generate(txt) w.to_file("grwordcloud.png")
不规则图形词云
#govrptwordcloudv2.py import jieba import wordcloud from scipy.misc import imread mask = imread("chinamap.jpg") excludes = { } f = open("新时代中国特色*.txt", "r", encoding="utf-8") t = f.read() f.close() ls = jieba.lcut(t) txt = " ".join(ls) w = wordcloud.wordcloud(\ width = 1000, height = 700,\ background_color = "white", font_path = "msyh.ttc", mask = mask ) w.generate(txt) w.to_file("grwordcloudm.png")
8. 程序设计方法学
8.1 实例13:体育竞技分析
自顶向下(设计) 分而治之
将一个总问题表达为若干个小问题组成的形式
使用相同的方法进一步分解小问题
解决复杂问题的有效设计方法
自底向上(执行) 模块化集成
逐步组建复杂系统的有效测试方法
分单元测试,逐步组装
#matchanalysis.py from random import random def printintro(): print("这个程序模拟两个选手a和b的某种竞技比赛") print("程序运行需要a和b的能力值(以0到1之间的小数表示)") def getinputs(): a = eval(input("请输入选手a的能力值(0-1): ")) b = eval(input("请输入选手b的能力值(0-1): ")) n = eval(input("模拟比赛的场次: ")) return a, b, n def simngames(n, proba, probb): winsa, winsb = 0, 0 for i in range(n): scorea, scoreb = simonegame(proba, probb) if scorea > scoreb: winsa += 1 else: winsb += 1 return winsa, winsb def gameover(a,b): return a==15 or b==15 def simonegame(proba, probb): scorea, scoreb = 0, 0 serving = "a" while not gameover(scorea, scoreb): if serving == "a": if random() < proba: scorea += 1 else: serving="b" else: if random() < probb: scoreb += 1 else: serving="a" return scorea, scoreb def printsummary(winsa, winsb): n = winsa + winsb print("竞技分析开始,共模拟{}场比赛".format(n)) print("选手a获胜{}场比赛,占比{:0.1%}".format(winsa, winsa/n)) print("选手b获胜{}场比赛,占比{:0.1%}".format(winsb, winsb/n)) def main(): printintro() proba, probb, n = getinputs() winsa, winsb = simngames(n, proba, probb) printsummary(winsa, winsb) main()
8.2 python程序设计思维
计算思维与程序设计
第三种人类思维特征
逻辑思维:以推理和演绎为特征,以数学为代表,a->b,b->c,a->c
实证思维:以实验和验证为特征,以物理为代表,引力波<-实验
计算思维:以设计和构造为特征,计算机为代表,汉诺塔递归
有非常明显的特征:抽象和自动化,抽象问题的计算过程并利用计算自动化求解(并不是抽象因果关系仅仅是抽象过程)
1+2+..+100 高斯 vs 累计
圆周率 高数求和 vs 蒙特卡洛方法
汉诺塔问题 逻辑推理的2的n次方-1 vs 递归
计算思维基于计算机强大的算力和海量的数据
抽象计算过程,关注设计和构造,而非因果
以计算机程序设计为主要实现手段
编程是将计算思维变为现实的手段
计算生态与python语言
从开源运动说起…
-1983年,richard stallman启动gnu项目
-1989年,gnu通用许可协议诞生,*软件时代到来 大教堂模式
-1991年,linus torvalds发布了linux内核 集市模式(成为主流)
-1998年,网景浏览器开源,产生了mozilla,开源生态逐步建立
计算生态以开源项目为组织形式,充分利用“共识原则”和“社会他人”组织人员,在竞争发展、相互依存和迅速更迭中完成信息技术的更新换代,形成了技术的自我演进路径。
开源思想深入演化和发展,形成了计算生态
计算生态是没有顶层设计、以功能为单位、具备三个特点:竞争发展、相互依存和迅速更迭
python
-以开源项目为代表的大量第三方库 python语言提供 > 13万个第三方库 并以两万+每年的速度发展
-库的建设经过野蛮生长和自然选择 同一个功能,python语言提供2个以上第三方库
-库之间相互关联使用,依存发展 python库间广泛联系,逐级封装
-社区庞大,新技术更迭迅速 alpha go深度学习算法采用python语言开源
api != 生态
创新:跟随创新、集成创新、原始创新
-计算生态加速科技类应用创新的重要支撑
-发展科技产品商业价值的重要模式
-国家科技体系安全和稳固的基础
刀耕火种 –> 站在巨人的肩膀上
-编程的起点不是算法而是系统
-变成如同搭积木,利用计算生态为主要模式
-编程的目标是快速解决问题
优质的计算生态 python123 由老师、产业人员共同筛选的优质生态
用户体验与软件产品
实现功能 –> 关注体验
用户体验指用户对产品建立的主管感受和认识
关心功能实现,更要关心用户体验,才能做出好产品
编程只是手段,不是目的,程序最终为人类服务
提高用户体验的方法
方法1:进度展示
-如果程序需要计算时间,可能产生等待,请增加进度展示
-如果程序需要若干步骤,需要提示用户,请增加进度展示
-如果程序可能存在大量次数的循环,请增加进度展示
方法2:异常处理
-当获得用户输入时候,对合规性需要检查,需要异常处理
-当读写文件时,对结果进行判断,需要异常处理
-当进行输入输出时,对运算结果进行判断,需要异常处理
其他方法:
-打印输出:特定位置,输出程序运行的过程信息verbose
-日志文件:对程序异常以及用户的使用进行定期记录
-帮助信息:给用户多种方式提供帮助
软件程序 到 软件产品,其核心关键就是用户体验
基本的程序设计模式
ipo
模块化设计
自顶向下设计
配置化设计 (自动轨迹绘制实例)
-引擎+配置:程序执行和配置分离,将可选参数配置化
-将程序开放变为配置文件编写,扩展功能而不修改程序
-关键在于接口设计,清晰明了,灵活扩展,这是一种更高级别的设计思路
应用开发的四个步骤:
1.产品定义 对应用需求充分理解和明确定义
-产品定义,而不仅是功能定义,要考虑商业模式
2.系统架构 以系统方式思考产品的技术实现
-系统架构,关注数据流、模块化、体系架构
3.设计与实现 结合架构完成关键设计及系统实现
-结合可扩展性、灵活性、是否适应未来需求变化等进行设计优化
4.用户体验 从用户角度思考应用效果
-用户至上,体验优先,以用户为中心构造软件产品
8.3 python第三方库安装
看见更大的python世界
13万个第三方库 全区社区
pypi
-python package index
-psf维护的展示全球python计算生态的主站
-学会检索并利用pypi,找到合适的第三方开发程序
3种安装方法:
-方法1(主要方法):使用pip命令
-方法2:集成安装方法
-方法3:文件安装方法
pip安装方法(最主要的方法)
pip -h 可以查看帮助
pip install <第三方库名> 安装
pip install –u <第三方库名> 升级
pip uninstall <第三方库名> 卸载
pip download <第三方库名> 下载单并不安装
pip show <第三方库名> 列出某个第三方库的详细信息
pip search 关键词 搜索第三方库
pip list 列出已安装的第三方库
集成安装方法
结合安装工具,批量安装,不过这样的安装工具不多
上一篇: PHP数字运算验证码
下一篇: python之中的迭代与迭代对象是什么?