LNU2020年春Python课堂笔记

第一章 Python语言基础 -1

1.Python简介

Python的发展

  • 1989年圣诞节 圣诞节期间,在阿姆斯特丹,吉多·范罗苏姆(Guido van Rossum)为了打发圣诞节的无趣,决心开发一个新的脚本解释程序
  • Python名字的灵感之所以选中Python作为该编程语言的名字,是取自英国20世纪70年代首播的电视喜剧《蒙提·派森的飞行马戏团》( Monty Python’s Flyying Circus)
  • 1991年发布的第1个Python版本
  • 2000年10月 发布Python 2.0 版本
  • 2008年12月 发布Python 3.0 版本
  • 2019年11月 至今Python 3.x 系列已成为主流
  • 最新版本Python 3.8.2 (官方网站下载 www.python.org)

Python的应用

Python 的主要应用领域
  • 常规软件开发
  • 图形处理
  • 科学计算
  • 大数据
  • Web开发
  • 网络爬虫
  • 系统运维
  • 人工智能
Python 的企业应用(略)

Python的特点

  • Python的设计哲学是优雅、简单和明确
  • Python既面向过程,也支持面向对象
  • Python是高级通用脚本编程语言
  • Python是解释型语言
  • Python是跨平台语言
  • Python是免费、开源,良好的生态
  • Python有丰富的类库

2.Python集成开发环境

  • PyCharm(由JetBrains打造的一款PythonIDE,分为专业版和社区版)
  • IDLE(Python安装包内置开发环境)
  • Python123(在线开发环境www.python123.io)
  • Jupyter(安装Anaconda自带的高级IDE)
  • Spyder(安装Anaconda自带的高级IDE)

3.用Python写程序

  • IDLE是一个Python shell(外壳),可以利用这个shell与Python进行人机交互。Python解释器即使响应用户输入的每条代码,给出输出的结果。
  • >>>是Python命令提示符。提示符是程序等待你键入信息时显示的符号。表示Python已经准备好了,在等着你键入Python指令。

例1:已知圆的半径是2.5,要求编写程序分别输出圆的周长和面积

解题思路:(将自然语言解题思路用Python语言实现人机交互)

半径 = 2.5
周长 = 2*π*半径
面积 = π*半径的平方
输出周长
输出面积

方法1:IDLE交互方式的程序

>>> r=2.5
>>> c=2*3.14*r
>>> s=3.14*r*r
>>> c
15.700000000000001
>>> s
19.625

方法2:IDLE文件方式的程序

r=2.5
c=2*3.14*r
s=3.14*r*r
print(c)
print(s)

4.Python程序语法元素分析

#E1-1.py
''' 已知圆的半径
    输出圆的周长和面积'''
r=2.5
c=2*3.14*r
s=3.14*r*r
print(c)
print(s)

(1)程序的格式框架

  • Python采用严格的“缩进”来表明程序的格式框架
  • 缩进指每一行代码开始前的空白区域,用来表示代码之间的包含和层次关系

(2)注释

在代码中加入的一行或多行辅助性文字信息,会被Python解释器略去,不被计算机执行

  • 单行注释
# 已知圆的半径输出圆的周长和面积
  • 多行注释
''' 已知圆的半径
    输出圆的周长和面积'''

(3)标识符

由用户来定义的用来标识某个实体(变量、常量、函数等)的一个符号。

  • 如程序中r、c、s属于标识符
  • 标识符由字母、下划线和数字组成(可以使用汉字),且不能以数字开头
  • 正确的标识符如: x_1、 myName等
  • 错误的标识符如:Test@2、1x等
  • 标识符的命名通常要“见名识意”,如:age、wordList
  • 标识符区分大小写,如age和Age是两个不同的标识符

(4)保留字(关键字)

  • 指被Python内部定义并保留使用的标识符
  • 用户编写程序时不能定义与保留字相同的标识符
  • Python的33个保留字列表
Flasedefifraise
Nonedelimportreturn
Trueelifintry
andelseiswhile
asexceptlambdawith
assertfinallynonlocalyield
breakfornot
classfromor
continueglobalpass

(5)变量

  • 在程序运行过程中,其值可以改变的量成为变量
  • 在Python中,不需要事先声明变量名及其类型,直接赋值即可创建任何类型的对象变量
  • 不仅变量的值是可以变化的,变量的类型也是可以变化的,如:
r=3.7 # r为浮点型
x1=2020 # x1位整数型
x1="武汉加油" # x1为字串符型 (成对的英文单引号或双引号)
  • 如何理解变量?
myUniversity="Lnu"
yourUniversity=myUniversity
yourUniversity="Neu"

(6)常量

  • 在程序运行过程中,其值不能改变的量成为常量
  • 如:3.14就是一个常量

(7).print()输出函数

是Python内置函数之一,用于输出数据对象

  • 格式:
    print(objects,sep='',end='\n')
  • objects:可以一次输出许多个对象, 输出多个对象时,需要用逗号分隔。
  • sep:设定输出多个对象时的分割符。若省略,默认为一个空格。
  • end:用来设定输出的结尾字符。若省略,默认值是换行符'\n',若输出后不想执行换行操作,也可以换成其他字符。
#E1-1.py
''' 已知圆的半径
    输出圆的周长和面积'''
r=2.5
c=2*3.14*r
s=3.14*r*r
print("圆的周长为:",c)
print("圆的周长为:",s)
程序执行结果:
圆的周长为:15.700000000000001
圆的面积为:19.625
>>>
#E1-1.py
''' 已知圆的半径
    输出圆的周长和面积'''
r=2.5
c=2*3.14*r
s=3.14*r*r
print("c=",c,end=' ')
print("s=",s)
程序执行结果:
c=15.700000000000001 s=19.625
>>>

(8).input()输入函数

是Python内置函数之一,用于完成数据的输入

  • 格式:
    <变量>=input(<提示信息>)
  • 在Python中,用input()函数实现变量的输入,无论用户在控制台输入字符串或数值,该函数都以字符串类型返回结果
#E1-1.py
''' 已知圆的半径
    输出圆的周长和面积'''
r=float(input("请输入半径"))
c=2*3.14*r
s=3.14*r*r
print("c=",c,end=' ')
print("s=",s)
程序执行结果:
请输入半径:5.6
c=35.168 s=98.4704
>>>

(9).eval()函数

是Python中经常使用的内置函数之一,用来解析给定的字符串表达式,并返回表达式的值。

  • 格式:
    <变量>=eval(<字符串表达式>)
  • 如:
>>>r=20
>>>eval("r")
>>>20

以上例句可以简单理解为“eval()用于去掉字符串两端的界线符”

#E1-1.py
''' 已知圆的半径
    输出圆的周长和面积'''
r=eval(input("请输入半径"))
c=2*3.14*r
s=3.14*r*r
print("c=",c,end=' ')
print("s=",s)
程序执行结果:
请输入半径:10.2
c=64.056 s=326.68559999999997
>>>

试一试

#E1-1.py
''' 已知圆的半径
    输出圆的周长和面积'''
import winsound
r=eval(input("请输入半径"))
c=2*3.14*r
s=3.14*r*r
winsound.Beep(500,1000)
print("c=",c)
print("s=",s)

函数

  • 实际编程中,一般将特定功能代码编写在一个函数里,便于阅读和复用,也使得程序模块化更好
  • 函数可理解为对一组表达特定功能表达式的封装,它与数学函数类似,能够接受变量并输出结果,如sin(x)
  • Python中函数包括Python解释器内置函数(如print()、input()、eval()等)、标准库函数、第三方库函数和用户自定义函数。

内置函数

  • Python解释器提供68个内置函数(如print()、input()、eval()等)

  • 这些函数不需要引用库可直接使用

  • 部分常用内置函数表

    print()input()eval()id()type()max()
    min()int()float()bool()str()len()
    open()pow()list()tuple()format()

标准库(模块)函数

  • Python有许多标准库,如os库、字符串正则匹配re库、数学库math、随机数random、日期时间datetime库等
  • 在使用这些模块中的函数时,需要先导入库import <库名>from <库名> import *
  • 例如
>>> import math() #导入math库
>>> math.sin(3) #返回弧度制3对应的正弦值

Python程序初识常见问题

问题1:Python程序执行出现“unexpected”(缩进)错误

解析:出现错误原因是出现未知缩进。一般来说,只要提示中包含“indent”,都是由于缩进不正确造成的。在Python中,缩进是语法的一部分。

问题2:Python程序执行出现“invalid syntax”(语法格式)错误

解析:出现错误原因是语法格式错误。一般来说,只要提示中包含单词“syntax”,都是由于语法格式错误造成的。如,缺少右括号)

问题3:Python程序执行出现“invalid character in identifier”(标识符中出现非法字符)错误

解析:出现错误原因是该行的标识符中出现非法字符。如本应该使用英文的符号()、"",却使用了中文的符号()、“”

课后作业 参考答案

1-5 CCBCB
6.(我的)

#E1-1-190102117.py
N=float(input("请输入整数"))**3
print(N)

6.(老师)

N**2

或者

pow(N,2)
#E1-2-190102117.py
yourUniversity=(input("请输入你的学校 "))
yourClass=(input("请输入你的班级 "))
yourName=(input("请输入你的姓名 "))
yourWord=(input("请输入你最想对驰援湖北、驰援武汉的广大医护人员说的一句话 "))
print(yourUniversity,end='的')
print(yourClass,end='的')
print(yourName,end='的想对驰援湖北、驰援武汉的广大医护人员说:')
print("“",yourWord,"”",sep='')

5.turtle库

  • turtle库是一个有趣的图形绘制库,也是Python标准库之一,使用时需先用命令导入turtle库:
    import turtlefrom turtle import *
  • turtle(海龟)图形绘制的方法可以想象为一个虚拟的小海龟,在画布上以坐标轴原点(0,0)位置未开始点,根据一组函数指令的控制来移动,从而在它爬行的路径上绘制出图形。

turtle库部分常用函数

  • 窗体设置
    • setup()
  • 画布设置
    • screensize()
    • bgcolor()
    • reset()
    • clear()
  • 小海龟
    • 画笔属性
      • colormode()
      • pensize() 或 width()
      • pencolor()
      • fillcolor()
      • color()
    • 画笔绘图状态
      • penup() 或 up() 或 pu()
      • pendown() 或 down() 或 pd()
      • begin_fill()
      • end_fill()
    • 移动绘制
      • forward() 或 fd()
      • backward() 或 back()
      • right() 或 rt()
      • left() 或 lt()
      • speed()
      • circle()
      • goto() 或 setpos() 或 setposition()
    • 小海龟状态
      • position() 或 pos()
      • distance()

绘制边长为100单位(像素)的正方形

#E1-2-1.py
import turtle
turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(90)
turtle.forward(100)

#E1-2-2.py
from turtle import *
forward(100)
left(90)
forward(100)
left(90)
forward(100)
left(90)
forward(100)

#E1-2-3.py
from turtle import *
for x in range(4):
	forward(100)
	left(90)

绘制边长为100单位(像素)的正方形及半径为50的圆

画笔抬起:penup() 或 up()
画笔落下:pendown() 或 down()
向前移动:forward()
移动到指定坐标位置:goto(x,y)
转角绘图:le() 或 right() 或 setup()
绘制圆形:circle()

#E1-3-1.py
import turtle
turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(90)       #绘制正方形

turtle.penup()        #画笔抬起
turtle.forward(200)   #向前移动200,但不绘制线条
turtle.pendown()      #画笔落下

turtle.circle(50)     #绘制半径为50的圆

#E1-3-2.py
from turtle import *
forward(100)
left(90)
forward(100)
left(90)
forward(100)
left(90)
forward(100)
left(90)

penup()
forward(200)
pendown()

circle(50)

#E1-3-2.py
from turtle import *
forward(100)
left(90)
forward(100)
left(90)
forward(100)
left(90)
forward(100)
left(90)

penup()
goto(200,0)    #将画笔移动到坐标(200,0)的位置
pendown()

circle(50)

#E1-3-4.py
from turtle import *
forward(100)
seth(90)       #设置当前画笔朝向为90度(相对于坐标轴)
forward(100)
seth(180)
forward(100)
seth(270)      #或seth(-90)
forward(100)
seth(0)

penup()
goto(200,0)
pendown()

circle(50)

绘制半径为50和100的同心圆

#E1-4-1.py
from turtle import *

circle(50)  #绘制内圆
penup()
goto(0,-50) #画笔移动到外圆绘制的起点
pendown()
circle(100) #绘制外圆

绘制内圆边框为红色、外圆边框为绿色的同心圆,画布为黑色

窗体设置:

  • 设置窗体大小:setup()
    画布设置:
  • 设置画布大小:screensize()
  • 画布背景色:bgcolor()
    画笔设置:
  • 画笔宽度:pensize()
  • 画笔颜色:pencolor()
#E1-5-1.py
from turtle import *
setup(500,500)     #窗体大小宽500,高500像素
screensize(800,600,"black")   #画布宽800,高600,背景黑色

''' screensize(800,600,"black") 也可写成
screensize(800,600)
bgcolor("black") 
'''

pensize(3)  #笔粗3像素
pencolor("red")
circle()

penup()
goto(0,-50)
pendown()

pencolor("green")  #绿色画笔
circle(100)

绘制内圆边框为红色且填充为黄色、外圆边框为绿色的同心圆,画布为黑色

画笔线条颜色:pencolor()
形状填充颜色:llcolor()
画笔线条和形状填充颜色:color()
开始填充颜色:begin_ll()
结束填充颜色:end_ll()
画笔移动速度:speed()

#E1-6-1.py
from turtle import *
setup(500,500)
screensize(800,600,"black")

pensize(3)
color("red","yellow") #红色画笔和黄色填充色
'''也可以写成
pencolor("red")
llcolor("yellow")
'''
begin_fill( ) #开始填充
circle(50)
end_fill( ) #结束填充

penup( )
goto(0,-50)
pendown( )

pencolor("green")
speed(10) #画笔移动 速度
circle(100)

RGB颜色模式是工业界的一种颜色标准,也是目前电子设备通用的颜色模式。

RGB颜色“三原色”原理:
通过打在显示屏上红®、绿(G)、蓝(B)三色电子光束的强弱变化,相互叠加来得到各式各样的颜色。

颜色RGB
(0,0,0)
(255,255,255)
(255,0,0)
绿(0,255,0)
(0,0,255)
(255,255,0)
(255,0,255)
(0,255,255)

Python中几种常用颜色的4种表示形式

颜色颜色英文RGB的整数值RGB的小数值十六进制串
black0,0,0(0,0,0)#000000
white255,255,255(255,255,255)#FFFFFF
red255,0,0(255,0,0)#FF0000
绿green0,255,0(0,255,0)#00FF00
blue0,0,255(0,0,255)#0000FF
yellow255,255,0(255,255,0)#FFFF00
gold255,215,0(255,215,0)#FFD700
violet238,130,238(238,130,238)#EE82EE
purple160,32,240(160,32,240)#A020F0

红色

  • pencolor (“red”)
  • pencolor(255,0,0)
  • pencolor(1,0,0)
  • pencolor("#FF0000")
    绿色
  • pencolor (“green")
  • pencolor(0,255,0)
  • pencolor(0,1,0)
  • pencolor("#00FF00")

colormode(1.0 [255]):

  • 设置画笔颜色模式,颜色模式取值1.0或255,
    colormode为1.0时r,g,b取值范围为[0,1.0]的小数,
    colormode为255时r,g,b取范围为[0,255]的整数。
  • 默认为colormode(1.0)。
  • 无参数时返回当前颜色模式值。
  • 例:colormode(255)

绘制内圆边框为红色且填充为紫色、外圆边框为绿色的同心圆,画布为黑色

#E1-6-2.py
from turtle import *
setup(500,500)
screensize(800,600,"black")

pensize(3)
colormode(255)
pencolor("red")
fillcolor(123,78,189)
begin_fill( )
circle(50)
end_fill( )

penup( )
goto(0,-50)
pendown( )

pencolor("green")
speed(20)
circle(100)

有趣的图像

#E1-8.py
from turtle import *

for x in range(100):
      forward(x)
      left(90)

reset()

for x in range(200):
      forward(x)
      left(91)

#E1-9.py
from turtle import *
bgcolor("black")
pensize(3)
pencolor("red")

for x in range(100):
      circle(x)
      left(91)

第二章 基本数据类型、运算符和表达式 -1

1.基本数据类型

2.运算符

3.常用内置函数

4.表达式、赋值语句与运算符的优先级

5.math库

数据类型概述

数据类型

  • 计算机对数据进行运算的时候,需要确定数据的类型和含义
  • 确定了数据类型,才能确定变量的存储以及操作
  • 计算机对数据的识别和处理有两个基本要求,确定性和高效性
  • Python中常用的数据类型包括数值类型、字符串类型、布尔类型等。

Python我们身边的计算器

数值类型

  • 整数
  • 浮点数
  • 负数

数值类型的运算

  • 数值运算操作符
  • 数值运算函数
  • math库

数值类型

数值类型

  • 表示数值或数字的数据类型
  • 在Python中提供3种数值类型,整数、浮点数和复数,分别对应数学中的整数、实数和复数。
>>> 3+5
8            #整数
>>> 3.14*2  
6.28         #浮点数
>>> 5+6j    #复数
(5+6j)

整数类型

  • 与数学中的整数概念一致
  • 共有4种进制表示:十进制、二进制、八进制和十六进制,默认采用十进制,其他进制需要增加引导符(不区分大小写)
  • 进制引导符
    • 二进制 0b或0B 如:0b101,0B1010
    • 八进制 0o或0O 如:0o127, 0O345
    • 十六进制 0x或0X 如:0x12AB, 0x34EF3
  • 理论上的取值范围是[-∞,+ ∞]
  • 实际上的取值范围受限于运行Python程序的计算机内存大小
  • 除极大数的运算外,一般认为整数类型没有取值范围限制
>>> 127     #十进制数127
127
>>> 0b1111111    #二进制数
127
>>> 0o177   #八进制数
127  
>>> 0x7f     #十六进制数
127
>>>    #无论输入的是几进制,输出默认都以十进制显示数据

浮点数类型

  • 与数学中实数的概念一致,表示带有小数的数值
  • Python要求浮点数类型必须带有小数部分,小数部分可以是0,以区分浮点数和整数,如100.0,100
  • 浮点数有两种表示方法:
    • 十进制表示: -55.96,3.1415926
    • 科学计数法:用e或E作为幂的符号,以10为基数,如 3.1E5表示3.1*10^5
  • 数值范围和小数精度受不同计算机系统的限制
  • 浮点运算结果中最长可输出17位数字,然而只有前15位数字确定是正确的,因此存在“不确尾数”
  • 对于除高精度科学计算外的绝大部分运算来说,浮点数类型的数值范围和小数精度足够“可靠”
  • 一般认为,浮点数类型没有数值范围限制,运算结果准确
>>> 77.56+88.98
166.54000000000002
>>> 3.14*2.5
7.8500000000000005
>>> 9.6e5
960000.0
>>> 12.56**20
9.5453704557821e+21

数值类型的运算

数值运算操作符

+、-、%、//、*、/、+-(正负号)、**

数值运算函数

  • abs(x)
  • max(x1,x2,x3)
  • round(x[,ndigits])
  • ……

math库

  • math.sqrt(x)
  • math.exp(x)
  • math.pow(x,y)
  • ……

数值运算操作符

数值运算符优先级 ,由低→高

+、-%//*、/+-(正负号)**

运算符描述
x+y加法,x与y之和
x-y减法,x与y之差
x*y乘法,x与y之积
x/y除法,x与y之商
x//y整除(地板除),x与y之整数商,即:不大于x与y之商的最大整数。如5/3返回1;-5/3返回-2
x%y取余,x与y之商的余数,也成为模运算
-x负号,x的负值,即:x*(-1)
+x正号,x本身
x**y乘方,x的y次幂,即:x^y,如:2**3返回8

注意

  • 数值运算可能改变结果的数据类型,类型的改变与运算符有关
  • 整数和浮点数混合运算,输出结果是浮点数
  • 整数之间运算,产生结果类型与操作符有关,除法运算(/)的结果是浮点数
  • 整数或浮点数与复数运算,输出结果是复数
>>> 77.56+8
85.56
>>> 6/3
2.0
>>> 8%3
2
>>> 8.0%3
2.0
>>>- 8%3
1
>>> 8%-3
-1
#用户输入一个整数,由计算机判断该数是偶数还是奇数
N=int(input("N="))
if N%2 == 0:
print("该数是偶数!")
else:
print("该数是奇数")

注意: x//y 返回不大于x与y之商的最大整数即结果向- ∞舍入

>>> 50//4
12
>>> 50.0//4
12.0
>>> -50//4
-13
>>> -50.0//4
-13.0

强调

  • 其中二元操作符(+、-、*、/、//、%、**)都可以与赋值符号(=)相连,形成增强赋值操作符,能够简化对同一变量赋值语句的表达
  • +=、-=、*=、/=、//=、%=、**=
    如:
    x=3
    x=x+1
    相当于:
    x=3
    x+=1
>>> x=25
>>> x%=2   #相当于x=x%2
>>>print( x)
1
>>> y=7.0
>>> y*=3   #相当于y=y*3
>>> print(y)
21.0

数值运算函数

Python解释器自身提供了一些预装函数,用于完成对参数的特定运算,称为“内置函数”,其中包括的主要用于数值运算的函数如下表所示:

函数说明
abs(x)返回x的绝对值,x可以为整数、浮点数或整数,x为复数时,返回它的模
divmod(x,y)返回x//y和x%y的结果
pow(x,y[,z])幂函数,返回x**y和或(x**y)%z的值
round(x[,n])对x进行四舍五入,保留n位小数;若省略n,则返回整数;若n为复数,则对小数点前n位进行四舍五入
max(x1,x2,…xn)返回多个参数中的最大值,n的值没有限定
min(x1,x2,…xn)返回多个参数中的最小值,n的值没有限定
sum([x1,x2,…xn])返回数值型序列中所有元素的和
>>> x=-25
>>> y=4
>>> abs(x)
25
>>>divmod(x,y)
(-7,3)
>>> pow(x,y)
390625
>>> pow(x,y,2)
1
>>> round(15.364,1)
15.4
>>>round(15.364,-1)
20.0
>>> max(10,20,15.38)
20
>>> min(10,20,15.38)
10
>>> sum((10,20,15.38))
45.38

math库

math库

  • math库是Python的标准库,提供了诸多的数学函数,可以实现整数和浮点数的数学运算。
  • math库提供了4个数学常数和44个函数。44个函数共分为4大类,包括16个数值表示函数,8个幂对数函数,16个三对数函数和4个高等特殊函数
  • 使用时要引用该库,格式为:
    import math
    from math import *
    from math import <函数名>
常数说明
math.e自然对数,值为2.718281828459045
math.pi圆周率pi,值为3.141592653589793
>>> import math
>>> math.pi*2**2
12.566370614359172
>>> PI=math.pi
>>> round(PI,3)*2**2
12.568

Math库的常用函数

函数说明
math.fabs(x)返回x的绝对值
math.ceil(x)返回不小于x的最小整数(向上取整)
math.floor(x)返回不大于x的最大整数(向下取整)
math.trunc(x)返回x的整数部分
math.modf(x)返回x的小数和整数
math.fmod(x,y)返回x与y的余数,注意与%返回结果略有不同
math.sqrt(x)返回x的平方根
math.pow(x)返回x的y次方
math.fsum([x,y,…])返回序列中各元素之和
math.factoria(x)返回x的阶乘

【例2-1】常用math库函数举例

>>> import math
>>> math.fabs(-5)		#返回-5绝对值,结果为浮点数5.0
5.0
>>> math.ceil(5.2)		#返回不小于5.2的最小整数
6
>>> math.ceil(-5.2)		#返回不小于-5.2的最小整数
-5
>>> math.floor(5.2) 		#返回不大于5.2的最大整数
5
>>> math.floor(-5.2) 	#返回不大于-5.2的最大整数
-6
>>> math.trunc(5.6)		#返回5.2的整数部分
5
>>> math.modf(5.2)		#返回5.2的小数和整数
(0.20000000000000018, 5.0)
>>> math.fmod(5,3)		#返回5除以2的余数
2.0

【例2-1】常用math库函数举例

>>> math.sqrt(3)		  #返回正数的平方根
1.7320508075688772
>>> math.sqrt(-3)		  #负数出错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: math domain error
>>> math.pow(5,3)		   #返回5的3次方
125.0
>>> 0.1+0.2+0.3			
0.6000000000000001
>>> math.fsum([0.1, 0.2, 0.3])	   #精确求和
0.6
>>> math.factorial(5)	 #返回5的阶乘
120

【例2-2】math库函数应用实例。分别输入三角形的三条边长,求三角形的面积、周长、最长边长和最短边长。

提示

  1. 根据海伦公式,p=(a+b+c)/2,S=√[p(p-a)(p-b)(p-c)]
  2. 假设输入的三条边满足 a>0 and b>0 and c>0 and a+b>c and b+c>a and a+c>b
#E2-2.py
import math
a=float(input("a="))
b=float(input("b="))
c=float(input("c="))
p=(a+b+c)/2
area=math.sqrt(p*(p-a)*(p-b)*(p-c))
circum=a+b+c
max_side=max(a,b,c)
min_side=min(a,b,c)
print("面积:",area)
print("周长:",circum)
print("长边为:",max_side)
print("短边为 :",min_side)

math库的其它函数(了解)

函数说明
math.gcd(x,y)返回整数x和y的最大公约数
math.degrees(x)将弧度转换为度
math.radians(x)将度转换为弧度
math.sin(x)返回x(弧度)的三角正弦值
math.asin(x)返回x的反三角正弦值
math.cos(x)返回x(弧度)的三角余弦值
math.acos(x)返回x的反三角余弦值
math.tan(x)返回x(弧度)的三角正切值
math.atan(x)返回x的反三角正切值
math.atan2(x,y)返回x/y的反三角正切值

赋值语句

>>> a=3
>>> b=5
>>> a+b
8
>>> a,b=3,5
>>> a+b
8
>>> a=3;b=5
>>> a+b
8
>>> x=y=9
>>> x
9
>>> y
9
  • Python中,赋值运算符=表示“赋值”,即将等号右侧表达式的计算结果赋给左侧变量,包含等号(=)的语句称为“赋值语句”:
    <变量> = <表达式>
  • 此外,还有一种同步赋值语句,同时给多个变量并行赋值:
    < 变量1>, …, < 变量N> = < 表达式1>, …, < 表达式N>
    也可以写成:
    < 变量1>=< 表达式1>;< 变量2>=< 表达式2>;……<变量N> =< 表达式N>
  • 链式赋值 将同一个值赋给多个变量
    <变量1>=<变量2>=…=<变量n >=<表达式>

【例2-3】编写程序输入两个数分别赋给变量x和y,交换变量x和y的值,并输出

#方法一
x=float(input("x="))
y=float(input("y="))
t=x
x=y
y=t
print("x=",x)
print("y=",y)
#方法二
x=float(input("x="))
y=float(input("y="))
x,y=y,x
print("x=",x)
print("y=",y)

第二章 基本数据类型、运算符和表达式 -2

字符串类型

字符串

  • 存储和处理文本信息在计算机应用中十分常见
  • 程序中字符串类型用于表示文本信息,是字符的序列表示
  • 在Python中,字符串中的文本要用界限符英文的单引号、双引号或三引号 括起来,如:“Python语言”、"您好"等。
>>> print(“《我和我的祖国》”)
《我和我的祖国》
>>> print(“《平凡的世界》”,”路遥”)
《平凡的世界》   路遥
>>> print(‘abc123@163.com’)
abc123@163.com
>>>print('950618',"190123112")
950618  190123112  
>>> print("210121197906256510")
210121197906266517
>>> print("'蒹葭苍苍,白露为霜。
所谓伊人,在水一方。
溯洄从之,道阻且长。
溯游从之,宛在水中央。"')
蒹葭苍苍,白露为霜。
所谓伊人,在水一方。
溯洄从之,道阻且长。
溯游从之,宛在水中央。

字符串

  • 作为同一字符串中的界限符,单引号和双引号不能混用
  • 当使用单引号作为界限符时,双引号可以作为字符串的一部分;当使用双引号作为界限符时,单引号可以作为字符串的一部分
>>> print("abc')
SyntaxError: EOL while 
scanning string literal 
>>> print("I’m Lily")
I’m Lily 
>>> print('She said: “good”')
She said: “good”

字符串操作符

操作符描述
x+y连接两个字符串x与y,如"a"+“b"返回"ab”
x*n或n*x将字符串x复制n次,如"a"*3返回"aaa"
x in s(或x not in s)如果x(不)是s的子串,返回True,否则返回False,如"bc"in"abc"返回True
x[i]索引,返回字串符x中的第i个字符
x[start🔚step]切片,返回索引从start到end中每step所取的子串,其中不包括end

in也称为成员运算符,即测试一个对象是否为另一个对象的元素;可进行序列(字符串,列表,元组),字典或集合的成员测试。

强调

  • 字符串类型数据是有长度的,其长度由字符串中包含的字符个数决定
  • Python中字符采用Unicode编码,每个中英文字符和符号长度都是1
  • 字符串正向递增序号(索引):最左侧字符序号为0,向右依次递增
  • 字符串索引 格式:
    <字符串或字符串变量>[索引]
>>> “温故而知新”[0]
‘温’
>>> s1= “温故而知新”
>>> s1[3]
‘知’
>>> s1[5]
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    str1[4]
IndexError: string index out of range

字符串切片

格式:
<字符串或字符串变量>[start:end:step]

>>> s1= “温故而知新”
>>> s1[0:4:1]
‘温故而知’
>>> s1[0:4:2]
‘温而’

【例2-4】基本的字符串操作符举例

>>> print(“蒹葭苍苍,”+’白露为霜’  )    #将两个字符串相连,返回一个新的字符串
蒹葭苍苍,白露为霜
>>> n=“加油!”
>>> print(n*3)	       #将“加油”复制3次,返回一个新的字符串
加油!加油!加油!
>>> “油” 	in n	#判断“油”是否是n的子串
True
>>> name=“王小雷”
>>> print(name[0])   	#返回字符串name索引为0的字符
王
>>> sj="蒹葭苍苍,白露为霜"
>>> print(sj[0:4])        #返回字符串sj的切片,从第0个字符到第4个字符,不包括第4                           个字符的子串
蒹葭苍苍

布尔类型

布尔类型

  • 布尔类型数据只有True和False两个值,用来表示逻辑真和逻辑假
>>> x=True
>>> x
True
>>> 5>3
True
>>> 3<5<2
False
>>> “Mike”<”Tom”
True

逻辑运算符

运算符描述实例
andTrue and False 结果是 Flase
orTrue and False 结果是 True
notnot True 结果是 Flase

【例2-5】求以下表达式的值

>>> 3<4 and 5<7
True
>>> x=10.2
>>> y=7.8
>>> not x >y
False
>>> 3>5 and a>3     #注意,此时并没有定义变量a
False
>>> 3>5 or a>3      #3>5的值为False,所以需要计算后面表达式
NameError: name 'a' is not defined
>>> 3<5 or a>3      #3<5的值为True,不需要计算后面表达式
True

强调:如右框图内例子,逻辑运算有一个称之为短路逻辑的特性:逻辑运算符右侧的表达式有时会被“短路”,实际是为了避免无用地执行代码

【例2-6】写出下列条件。

(1)判断ch是否为小写字母。
(2)判断ch既不是字母也不是数字字符。
答案:
(1)ch>=‘a’ and ch<=‘z’
(2)not((ch>=‘A’ and ch<=‘Z’) or (ch>=‘a’ and ch<=‘z’) or (ch>=‘0’ and ch<=‘9’))

类型转换函数

函数说明
type(x)返回x的数据类型
int(x)将x表示的浮点数、字符串或布尔型转换为一个整数,若x为字符串,则必须是只包含数字的字符串,如"123"才能转换
float(x)将x表示的整数、字符串或布尔型转换为一个浮点数
str(x)将x表示的整数、浮点数或布尔型转换为字符串
bool(x)将x表示的整数、浮点数或字符串转换为布尔值,当x为0、空字符串、空值(None)时返回False,否则返回True

【例2-7】type( )函数应用举例

>>> type(100)
<class ‘int’>                 #返回整数100的数据类型为int整数
>>> type(20.3*5)
<class ‘float’>          #返回表达式20.3*5的数据类型为float浮点数
>>> type("hello world")
<class ‘str’>     #返回字符串“hello world”的数据类型为字符串str
>>> type(True)
<class ‘bool’>   #返回True的数据类型为布尔型bool

【例2-8】常用类型转换函数int( )应用举例

>>> int(5.9) 	# 将浮点数5.9转换为整数(截断取整) ,不四舍五入
5
>>> int(‘123’)       # 将字符串(必须是不包含小数点的数字串)转换为整数
123
>>> int('1.23')	# 转换的数字串中不可以包含小数点
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int( ) with base 10: '1.23‘
>>> int(True) 	# 将布尔型True转换为整数1
1
>>>int(False) 	#将布尔型False转换为整数0
0

【例2-9】常用类型转换函数float( )应用举例

>>> float(1)	# 将整数1转换为浮点数
1.0
>>> float('123')  	# 将字符串'123'转换为浮点数
123.0
>>> float(‘a’)           # 转换的字符串必须是数字串
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: could not convert string to float: 'a‘
>>> float(True) 	# 将布尔型True转换为浮点数1.0
1.0
>>>float(False) 	#将布尔型False转换为浮点数0.0
0.0

【例2-10】常用类型转换函数str( )应用举例

>>> str(520)	# 将整数520转换为字符串’520’
'520‘
>>> str(520.6)	# 将浮点数520.6转换为字符串’520.6’
'520.6‘
 >>> str(123e5)      # 将浮点数123e5转换为字符串
'12300000.0‘
>>> str(True) 	# 将布尔型True转换为字符串’True’
'True‘
>>>str(False) 	#将布尔型False转换为字符串’False’
'False'

【例2-11】常用类型转换函数bool( )应用举例

>>> bool(0)
False
>>> bool(1)
True
>>> bool(10)
True
>>> bool(0.0)
False
>>> bool(0.1)
True
>>> bool(5.21)
True
>>> bool("")
False
>>> bool("abc")
True
>>> bool()
False
>>> bool(None)
False

当其他类型数据转换为布尔类型时,值为0的整数、浮点数、空字符串、空值(None)等被看作是False,其他值均被看作是True

关系运算符

在解决问题时常常需要比较两个对象的大小,Python中的关系运算符如表所示

运算符描述实例
==等于5==4 返回 False
!=不等于5!=4 返回 True
<>不等于5<>4 返回 True
>大于4>5 返回 False
<小于4<5 返回 True
>大于等于9>=10 返回 False
<=小于等于9<=10 返回 True

【例2-12】求以下表达式的值

>>>"acc"<"b"
True
>>>"sunck"=="sunck"
True
>>>"acc"<"bcc"
True
>>>"zaa">"azz"
True

【例2-13】求以下表达式的值

>>> 1<2<3
True
>>> 1<2>3
False
>>> 1<3>2
True

强调:数值比较时按值的大小进行比较,字符串的比较则按ASCII码值的大小进行比较,按照关系运算符左右两边的字符串从第1个字符开始依次对对应位置的字符进行比较

运算符优先级

  • Python语言支持多种类型的运算符:数值(算术)运算符、关系(比较)运算符、逻辑运算符、成员运算符、位运算符、身份运算符等。
  • 实际应用中, 多种运算符经常混合使用,表达式也由多种运算混合而成,每种运算符之间有优先级顺序,而不同类型运算符间也存在优先级顺序,总体上的优先级顺序为:
    逻辑运算符 → 关系运算符 → 算数运算符
    (各种类型运算符优先级 ,由低→高)

第三章 程序控制结构-1

1.程序基础

2.顺序结构

3.分支结构

4.循环结构

5.嵌套程序

6.程序的异常处理(选讲)

7.random库

1.程序基础

Python程序文件一般包括注释、模块导入、函数定义和程序主体等几个部分
Python程序由三种基本结构组成:顺序结构、分支结构(选择结构)、循环结构

2.顺序结构

程序按照语句顺序依次执行的一种运行方式

#E1-1.py
‘’’已知圆的半径
输出圆的周长和面积’’’
r=2.5
c=2*3.14*r
s=3.14*r*r
print("c=",c,end=‘ ‘)
print("s=",s)

#E1-2.py
#绘制正方形
import turtle
turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(90)
turtle.forward(100)

3.分支结构

分支结构(选择结构)是根据条件判断的结果控制不同分支执行的结构

  • 单分支结构
  • 双分支结构
  • 多分支结构

3.1单路分支结构

单分支结构是一种取舍结构,就是只有 一种选择,要么选,要么不选,即符合某一条件就单独处理,不符合就不做处理
if <条件表达式>:
  <语句块>
语法格式
  • 当<条件表达式>为True时,执行<语句块>中若干语句,否则不执行任何操作。
  • <条件表达式>可以是关系表达式、逻辑表达式、算术表达式等。
  • <语句块>前有缩进,冒号“:”不能缺省。
【例3-1】输入一个整数,如果是偶数则输出“这是个偶数”,否则什么也不输出
#E3-1-1.py
N=int(input("请输入一个整数:"))
if N%2==0:
  print("这是个偶数")

#E3-1-2.py
N=eval(input("请输入一个整数:"))
if N%2==0:
  print("这是个偶数")
注意print()前要有缩进 4个空格
【例3-2】任意输入两个数x、y,请将这两个数由小到大输出

分析:
(1)输入x、y
(2)如果x>y,则交换x和y,否则不交换
(3)最后输出x、y

#E3-2-1.py
x=int(input("请输入x:"))
y=int(input("请输入y:"))
if x>y:
  x,y=y,x
print(x,y)

#E3-2-2.py
x,y=eval(input("请输入x、y:"))
if x>y:
  x,y=y,x
print(x,y)
【例3-3】任意输入三个数x、y、z,请将这三个数由小到大输出

分析:
(1)输入x、y 、z
(2)如果x>y,则交换x和y,否则不交换
(3)如果x>z,则交换x和z,否则不交换
(4)如果y>z,则交换y和z,否则不交换。
(5)最后输出x、y、z

#E3-3-1.py
x,y,z=eval(input("输入3个数(用逗号分隔):"))
if x>y:
  x,y=y,x
if x>z:
  x,z=z,x
if y>z:
  y,z=z,y
print(x,y,z)

#E3-3-2.py
x,y,z=eval(input("输入3个数(用逗号分隔):"))
if x>y:
  x,y=y,x
if y>z:
  y,z=z,y
if x>y:
  x,y=y,x
print(x,y,z)

程序运行结果
输入3个数(用逗号分隔):5,3,7
3 5 7

【例3-4】输入腋下体温值t,根据如下情况分别输出:

t<36.1输出:您的体温偏低
36.1<=t<=37.2 输出:您的体温正常
37.3<t输出:您的体温偏高

#E3-4.py
t=eval(input("请输入体温值:"))
if t<36.1:
  print("您的体温偏低")
if 36.1<=t<=37.2:
  print("您的体温正常")
if 37.3<t:
  print("您的体温偏高")

程序运行结果
请输入体温值:35
您的体温偏低
请输入体温值:36.7
您的体温正常
请输入体温值:38.5
您的体温偏高

3.2 random库

random库
  • 是Python的一个标准库,包含多种生成伪随机数的函数
  • 该库中的大部分函数都基于random.random( )函数
  • prandom.random( )函数使用梅森旋转算法(Mersenne twister)生成伪随机数。
  • 使用random库的功能前,需要先导入random库
为什么是伪随机数?

随机数随机事件是不确定性的产物,其结果是不可预测、产生之前不可预见
无论计算机产生的随机数看起来多么“随机”,它们也不是真正意义上的随机数
因为计算机是按照一定算法产生随机数的,其结果是确定的、可预见的、称为“伪随机数”。

random库的常用函数
函数说明
random()生成一个[0.0,1.0]之间的随机小数
randint(a,b)生成一个[a,b]之间的整数
uniform(a,b)生成一个[a,b]之间的随机小数
randrange(start,stop[,step])生成一个[start,stop]之间以step为步数的随机整数
seed(a=None)初始化随机数种子,默认值为当前系统时间,一般用一个整数作为随机数种子,如seed(125),seed(200)等
只要种子相同,每次生成的随机数也相同,这样便于测试和同步数据
>>> import random
>>> random.random()
0.5849568047225475
>>> random.uniform(10,20)
15.996127922390558
>>> random.randint(0,10)
8
>>> random.seed(100)
>>> random.randint(0,10)
2
>>> random.randint(0,10)
7

>>> from random import *
>>> random()
0.45492700451402135
>>> uniform(10,20)
17.70783805659022
>>> randint(0,10)
6
>>> seed(100)
>>> randint(0,10)
2
>>> randint(0,10)
7
【例3-5】游戏猜数字:随机产生一个0-10间的整数,玩家通过键盘输入一个数竞猜,若猜中,则提示“恭喜你猜对啦”,否则什么也不提示

分析:
(1)随机产生0-10间的整数赋给变量num
(2)通过键盘输入一个数赋给变量x
(3)如果 x== num,输出“恭喜你猜对啦”

#E3-5.py
from random import *
num=randint(0,10)
x=int(input("请输入一个数:"))
if num==x:
  print("恭喜你猜对啦!")
#print("随机数是:",num)
【例3-6】登录程序:用户通过键盘输入用户名和密码,如果输入的用户名为空,输出“用户名不能为空”;如果输入的密码为空,输出“密码不能为空”;如果输入的用户名为“abc”,并且密码为”123”,输出“欢迎进入本系统”,否则什么也提示

分析:
(1)通过键盘输入用户名赋给userName,输入密码赋给passWord
(2)如果输入的用户名为空,输出“用户名不能为空”
(3)如果输入的密码为空,输出“密码不能为空”
(4)如果输入的用户名为“abc”,并且密码为“123”,输出“欢迎进入本 系统”

#E3-6.py
#登录程序
userName=input("请输入用户名:")
passWord=input("请输入密码:")
if userName=="":
  print("用户名不能为空")
if passWord=="":
  print("密码不能为空")
if userName=="abc" and  \ 
passWord=="123":  # \ 为续行符
  print("欢迎进入本系统")

第三章 程序控制结构-2

3.2 双路分支结构

双路分支结构是一种二选一,即一个条件分两种情形处理
if <条件表达式>:
  <语句块1>
else:
  <语句块2>
语法格式
  • 当<条件表达式>为True时,执行<语句块1>,否则执行<语句块2>。
  • <条件表达式>可以是关系表达式、逻辑表达式、算术表达式等。
  • <语句块>前有缩进,冒号:不能缺省。
【例3-7】 改写【例3-1】程序,输入一个整数,如果是偶数则输出“这是个偶数”,否则输出这是个“奇数”
#例3-1
#E3-1-1.py
N=int(input("请输入一个整数:"))
if N%2==0:
  print("这是个偶数")

#例3-7
#E3-7.py
N=int(input("请输入一个整数:"))
if N%2==0:
  print("这是个偶数")
else:
  print(“这是个奇数")
【例3-8】游戏猜数字,改写【例3-5】程序:随机产生一个0-10间的整数,玩家通过键盘输入一个数竞猜,若猜中,则输出“恭喜你猜对啦!”,否则输出“很遗憾,没有猜对哟!”
#例3-5
#E3-5.py
from random import *
num=randint(0,10)
x=int(input("请输入一个数:"))
if num==x:
  print("恭喜你猜对啦!")
print("随机数是:",num)

#例3-8
#E3-8.py
from random import *
num=randint(0,10)
x=int(input("请输入一个数:"))
if num==x:
  print("恭喜你猜对啦!")
else:
  print("很遗憾,没有猜对哟!")
print("随机数是:",num)
【例3-9】改写【例3-6】登录程序:用户通过键盘输入用户名和密码,如果输入的用户名为空,输出“用户名不能为空”;如果输入的密码为空,输出“密码不能为空”;如果输入的用户名为“abc”,并且密码为”123”,输出“欢迎进入本系统”,否则输出“用户名或密码错误”
#例3-6
#E3-6.py
userName=input("请输入用户名:")
passWord=input("请输入密码:")
if userName=="":
  print("用户名不能为空")
if passWord=="":
  print("密码不能为空")
if userName=="abc" and passWord=="123":
  print("欢迎进入本系统")

#例3-9
#E3-9.py
userName=input("请输入用户名:")
passWord=input("请输入密码:")
if userName=="":
  print("用户名不能为空")
if passWord=="":
  print("密码不能为空")
if userName=="abc" and passWord=="123":
  print("欢迎进入本系统")
else:
  print("用户名或密码错误")
【试一试】编写程序计算 y = |x^2 - 25|^0.5

提示:
条件(1) 与(2) ,哪个放在if 后面做为if的条件表达式?

  1. x<=-5或x>=5
  2. -5<x<5
#test1.py
# 方法1
import math
x=eval(input("输入x:"))
if -5<x<5:
  y=math.sqrt(25-x*x)
else:
  y=math.sqrt(x*x-25)
print("y=",y)

#test1.py
方法2
import math
x=eval(input("输入x:"))
if  x<=-5 or x>=5:
  y=math.sqrt(x*x-25)
else:
  y=math.sqrt(25-x*x)   
print("y=",y)

# x=int(input("输入x:")))
【试一试】编写程序,输入一个数,利用turtle库绘制画笔大小为3,半径为100的圆形。并且当输入的数是偶数时,填充颜色为蓝色;当输入的数是奇数时,填充颜色为红色。

提示:
(1)turtle库中有关函数
画圆 circle(),画笔大小pensize(),填充fillcolor(),开始填充begin_fill(),结束填充end_fill()
(2) 判断一个数是否是偶数的条件表达式 N%2==0

#test2.py
from turtle import *
N=int(input("N="))
if N%2==0:
  fillcolor("blue")
else:
  fillcolor("red")
pensize(3)
hideturtle()
begin_fill()
circle(100)
end_fill()

思考:

  • hideturtle()函数的作用是什么?
  • if…else…语句是否可以放在程序的其它位置?
  • 能否改写程序,用input函数分别输入N,画笔大小,圆半径的值。

3.2 双路分支结构-扩展

if <条件表达式>:
  <表达式1>
else:
  <表达式2>

<表达式1> if <条件表达式> else <表达式2>

功能:

  • 当条件表达式为True时,执行表达式1,否则执行表达式2
#例3-8
#E3-8.py
from random import *
num=randint(0,10)
x=int(input("请输入一个数:"))
if num==x:
  print("恭喜你猜对啦!")
else:
  print("很遗憾,没有猜对哟!")
print("随机数是:",num)
# 可写成print("恭喜你猜对啦!") if num==x else print("很遗憾,没有猜对哟!")
#例3-7
#E3-7.py
N=int(input("请输入一个整数:"))
if N%2==0:
  print("这是个偶数")
else:
  print("这是个奇数")
# 可写成print(“这是个偶数”)  if  N%2==0 else print(“这是个奇数")

3.3 多路分支结构

if <条件表达式1>:
  <语句块1>
elif <条件表达式2>:
  <语句块2>
……
elif <条件表达式n>:
  <语句块n>
[else:
  <语句块n+1>]

3.3 多路分支结构

【例3-10】用多路分支结构改写【例3-4】,即输入腋下体温值t,根据如下情况分别输出:

t<36.1输出:您的体温偏低
36.1<=t<=37.2 输出:您的体温正常
37.3<t输出:您的体温偏高

#E3-4.py
t=eval(input("请输入体温值:"))
if t<36.1:
  print("您的体温偏低")
if 36.1<=t<=37.2:
  print("您的体温正常")
if 37.3<t:
  print("您的体温偏高")

#E3-10.py
t=eval(input("请输入体温值:"))
if t<36.1:
  print("您的体温偏低")
elif  t<=37.2:
  print("您的体温正常")
elif 37.3<t:
  print("您的体温偏高")
# 或 else:
思考:
  • 上面两个方法在程序的执行效率上会有不同吗?
  • 在使用多路分支结构时,是不是所有情况下,最后一个分支都可以是用elif 或 else?
【例3-11】输入学生成绩 ,根据成绩进行分类:

90分以上优秀
80~89分 良好
70~79分 中等
60~69分 及格
低于60分不及格

#E3-11.py
score=eval(input("成绩:"))
if score>=90:
  print("优秀")
elif score>=80:
  print("良好")
elif score>=70:
  print("中等")
elif score>=60:
  print("及格")
else:
  print("不及格")

课堂小结

  • 单路分支结构
if  <条件表达式>:
  <语句块>
  • 双路分支结构
if  <条件表达式>:
  <表达式1>
else:
  <表达式2>
  • 多路分支结构
if <条件表达式1>:
  <语句块1>
elif <条件表达式2>:
  <语句块2>
……
elif <条件表达式n>:
  <语句块n>
[else:
  <语句块n+1>]

课后作业

1.新建程序文件 “姓名-3-1.py”,从键盘输入一个字符,赋值给变量ch,判断它是英文字母、数字还是其他字符。
提示:
分析下列三种情况

  • 英文字母:
    ch>=“a” and ch<=“z” or ch>=“A” and ch<=“Z”
  • 数字字符:ch>="0"and ch<=“9”
  • 其他字符

2.中国古代关于人类年龄阶段的划分
据秦汉的《礼记·礼上第一》记载:“人生十年曰幼,学。二十曰弱,冠。三十曰壮,有室。四十曰强,而仕。五十曰艾,服官政。六十曰耆,指使。七十曰老,而传。八十、九十曰耄。百年曰期,颐。”
要求 :编写程序“姓名-3-2.py” ,当输入一个年龄后,按中国古代年龄段划分,给出这个年龄的年龄段名称。如输入 年龄“20”,输出“弱”

3.为了评价一个人是否肥胖,1835年比利时统计学家和数学家凯特勒提出一种简便的判定指标BMI(身体质量指数)。BMI的定义如下:BMI=体重(kg)÷身高2(m)按照这个计算方法,WHO(世界卫生组织)1997年公布了一个判断人肥胖程度的BMI标准,后来又公布了中国参考标准。
要求 :编写程序“姓名-3-3.py” ,根据上述资料,输入一个人的体重和身高,按中国参考标准输出BMI分类值

4.中国大学Mooc平台上第三周的学习,并按时完成第三周的单元测试,单元测试截止时间3月22日0时。

第三章 程序控制结构-3

知识回顾与导入

#E1-2-2.py
#绘制边长为100单位(像素)的正方形
from  turtle  import *
forward(100) #向前移动100单位(像素),画A边
left(90)#向左(逆时针)转90度
forward(100) #向前移动100单位(像素),画B边
left(90)   #向左(逆时针)转90度
forward(100)#向前移动100单位(像素),画C边
left(90)  #向左(逆时针)转90度
forward(100)#向前移动100单位(像素),画D边
left(90)  #向左(逆时针)转90度

#E1-2-3.py
#绘制边长为100单位(像素)的正方形
from  turtle  import *
for x in range(4):
  forward(100)
  left(90)        #行缩进4个字符

#有趣的图形(选做) 
#E1-8.py
from turtle import *
for x in range(100):
  forward(x)
  left(90)        #行缩进4个字符
reset()
for x in range(200):
  forward(x)
  left(91)        #行缩进4个字符

#E1-9.py
from turtle import *
bgcolor("black")
pensize(3)
pencolor("red")
for x in range(100):
  circle(x)
  left(91)        #行缩进4个字符

#例3-8
#E3-8.py
from random import *
num=randint(0,10)
x=int(input("请输入一个数:"))
if num==x:
   print("恭喜你猜对啦!")
else:
   print("很遗憾,没有猜对哟!")
# 可写成:print("恭喜你猜对啦!") if num==x else print("很遗憾,没有猜对哟!")
print("随机数是:",num)

4 循环结构

  • 在程序设计过程中,经常需要将一些代码按照要求重复多次执行,这时就需要用到循环结构
  • Python有两种类型的循环语句,分别是for循环和while循环。
  • for循环为确定次数的循环,也称“遍历循环”,循环次数采用遍历结构中的元素个数来体现
  • while循环为非确定或确定次数的循环,通过条件判断是否继续执行循环体

4.1 while 循环

while循环是“当型”循环结构,当条件满足时执行循环体
while  <条件表达式>:
  <循环体>
功能
  • while语句执行时,先计算<条件表达式>的值
  • 当<条件表达式>的值为True时,循环条件成立,执行循环体;然后继续判断<条件表达式>的值是否为True,若是,则继续执行循环体,如此周而复始
  • 直到<条件表达式>的值为False时停止循环的执行,退出循环
强调
  • while语句是先判断再执行,所以循环体有可能一次也不执行
  • 当循环体由多条语句构成时,必须用缩进对齐的方式组成一个语句块来分隔子句,否则会产生错误
  • 在循环体内必须有改变循环变量值的语句,否则如果<条件表达式>永远为True,循环将会无限地执行下去,造成死循环
【例4-1】编写程序,循环输出数值1,2,…,5
#例4-1
#E4-1.py
#用顺序结构编写
print(1)
print(2)
print(3)
print(4)
print(5)

#例4-1
#E4-1.py
#用while循环结构编写
i=1
while i<=5:
  print(i)
  +=1
【例4-2】 编写程序,求1+2+3+……+100的和
#例4-2
#E4-2.py
i=1
s=0
while i<=100:
  s=s+i
  i=i+1
print(“s=”,s)

分析:

  • s表示累加和;i 控制循环的次数,及作为每次相加的加数
  • s的初值是0,i的初值是1
  • 每次循环的 循环体:
    s=s+i#或s+=i
    i=i+1#或i+=1
  • 循环条件:
    i<=100
【扩展】 编写程序,求1+2+3+……+100的偶数和
#E4-2-2.py
#求1+2+….+100的偶数和
i=1
s=0
while i<=100:
if i%2==0:
  s=s+i
  i=i+1
print(s)

#E4-2.py
#求1+2+…+100的和
i=1
s=0
while i<=100:
  s=s+i
  i=i+1
print(“s=”,s)
【例4-3】从键盘输入若干个正数,求所有正数之和。当输入0或负数时,程序结束。
#例4-3
#E4-3.py
s=0
x=eval(input("请输入一个正数:"))
while x>0:
 s=s+x
 x=eval(input("请输入一个正数:"))
print("s=",s)

分析:

  • 求累加和问题
  • 用s表示累加和,s的初值是0,x表示每次输入的数,作为加数
  • 每次循环的 循环体:
    s=s+x #或s+=x
    x=input(请输入一个正数:”)
  • 循环次数不确定,循环条件是:
    x>0
【例4-3】从键盘输入若干个正数,求所有正数之和。当输入0或负数时,程序结束。
#例4-3
#E4-3.py
s=0
x=eval(input("请输入一个正数:"))
while x>0:
  s=s+x
  x=eval(input("请输入一个正数:"))
print("s=",s)

程序运行结果
请输入一个正数:26
请输入一个正数:1
请输入一个正数:3
请输入一个正数:-5
s= 30

【例4-4】用哨兵值控制循环——分析考试情况:依次输入学生的分数,最后输出最高分,最低分和平均分

分析:

  • 用哨兵值控制循环就是每循环一次,都要检测一下这个哨兵值是否出现,一旦出现就退出循环
  • 假设用变量score表示每次输入的成绩,同时作为哨兵值,当score == -1时退出循环
  • 初始化:将第一次输入score作为maxScore,minScore, sumScore=0,i=0
  • 循环条件: score != -1
  • 循环体:
    将当前成绩求累加和,作为总成绩sumScore,同时记录当前输入的次数i。
    将当前输入的分数与当前最高分、最低分相比较,记录最高分、最低分
  • 循环结束后,输出sumScore/i表示平均分,最高分maxScore,最低分minScore
score=maxScore=minScore=eval(input("请输入分数:")) 
sumScore=i=0#初始化总成绩sumScore和人数 i
while score != -1:
  sumScore+=score  #总成绩累加求和
  i+=1#总人数累加求和
  maxScore=score if score>maxScore else maxScore   #记录最高分
  minScore=score if score<minScore else minScore #记录最低分
  score=eval(input("请输入分数:"))
print("最高分:",maxScore)
print("最低分:",minScore)
print("平均分:",round(sumScore/i,1))
课后作业

1.新建程序文件 “姓名-4-1.py”,用while循环编写程序绘制边长为100的正方形。
2.新建程序文件 “姓名-4-2.py”,用while循环编写程序,输出200内所有能被7或9整除的自然数的和
提示:请参考【例4-2】扩展
3.新建程序文件 “姓名-4-3.py”,用while循环改写【例3-8】游戏猜数字程序:随机产生一个0-10间的整数,玩家通过键盘输入一个数竞猜,若猜中,则输出“恭喜你猜对啦!”,否则输出“很遗憾,没有猜对哟!”,直到用户输入-1结束游戏
提示:参考程序在下一页,请填 空,并回答break的作用是什么?

import random
num=random.randint(0,10)
x=eval(input("请输入一个数:"))
while ___【空1】________:
  if num==x:
    print("恭喜你猜对了!")
    break
  else:
    print("很遗憾,没有猜对哟!")
  x=_____【空2】_____

第三章 程序控制结构-4

4 循环结构

  • 在程序设计过程中,经常需要将一些代码按照要求重复多次执行,这时就需要用到循环结构
  • Python有两种类型的循环语句,分别是for循环和while循环。
  • for循环为确定次数的循环,也称“遍历循环”,循环次数采用遍历结构中的元素个数来体现
  • while循环为非确定或确定次数的循环,通过条件判断是否继续执行循环体

4.2 for循环

for循环是遍历循环,特别适用于循环次数确定的情况
for <循环变量> in <序列对象>:
	<循环体(语句块)>
功能
  • 从遍历的序列对象结构中逐一提取元素,作 为循环变量,对于每个提取的元素执行一次循环体语句块
  • 遍历的序列结构可以是字符串、元组、列表、文件、range()函数返回的可迭代对象等
  • <循环变量>用于控制循环次数,也可以参与到循环体中
【例4-5】字符串的遍历 ——循环访问字符串中的每个字符

要求:编写程序,输出字符串"PythonStudy"中的每个字符,并用空格分隔,即输出P y t h o n S t u d y

#例4-5
#E4-5.py
for i in "PythonStudy":
  print(i,end=‘ ’)  # 单引号内是空格字符

程序运行结果
P y t h o n S t u d y

其他如:列表、元组、字典、集合、文件等的遍历将在后续章节介绍

※range( )函数在for 循环中的应用
  • range( )函数一般格式为:range([start,]end[,step])
  • range( ) 函数返回的是可迭代对象 ,也就是生成一个从start值开始,到end值结束(但不包括end)的数字序列。在for循环中的作用是通过该函数可以控制循环的次数
  • 如:range(1,10,2) ,range(1,10),range(10)
  • start:表示计数的开始, 若省略默认值是0
  • end:表示计数的结束,但不包括end ,如range(3)表示计数范围是0,1,2
  • step:表示步长,若省略默认值是1,如range(0,3)相当于range(0,3,1)
【例4-6】改写【例4-1】程序,循环输出数值1到5
#例4-1
#E4-1.py
#用顺序结构
print(1)
print(2)
print(3)
print(4)
print(5)

#例4-1
#E4-1.py
#用while循环结构
i=1
while i<=5:
  print(i)
  i+=1

#例4-6
#E4-6.py
#用for循环结构
for i in range(1,6):
  print(i)

#思考:print(i,end=‘ ‘)
注意体会
# 循环变量=初值
while 循环变量<=终值:
  循环体
  循环变量+=递增值
i=1
while i<=5:
  print(i)
  i+=1

for 循环变量 in range(初值,终值,递增值):
 循环体(语句块)
for i in range(1,6):
  print(i)
【例4-7】改写【例4-2】程序,求1+2+3+……+100的和
#例4-2
#E4-2.py
i=1 
s=0
while i<=100:
  s=s+i
  i=i+1
print(“s=”,s)

#例4-7
#E4-7.py
s=0
for i in range(1,101):
  s += i   #或s=s+i
print(“s=",s)
【例4-8】使用turtle库绘制红色五角星图形,效果如图所示,五角星非相邻两个顶点间的距离为200

分析:

  • 绘制过程以S为起始点绘制直线,长度为200,此时到达五角星的另外一个顶点
  • 然后向右转144°,再继续绘制直线,长度为200
  • 如此反复5次,最终绘制出五角星
  • 绘制顺序如图中箭头方向所示
#E4-8.py
from turtle import *
setup(400,400)  #设置窗体大小
penup()
goto(-100,50)   #设置绘制起点
pendown()
pencolor(“red”);fillcolor("red")
begin_fill()
for i in range(5):
  forward(200)
  right(144)
end_fill()
hideturtle()
有趣的图形1
# E1-8.py
from turtle import *
for x in range(100):
  forward(x)
  left(90)
reset()
for x in range(200):
  forward(x)
  left(91)
有趣的图形2
#E1-9.py
from turtle import *
bgcolor("black")
pensize(3)
pencolor("red")

for x in range(100):
  circle(x)
  left(91)
课后作业

1.新建程序文件“姓名-4-1.py”,用for循环编写程序绘制边长为100的正方形。
2.新建程序文件 “姓名-4-2.py”,用for循环编写程序,输出500内所有能被7或9整除的自然数
3.讨论:读程序并上机调试,将本程序的含义写在答题处,并将程序及程序的运行结果截图上传

第三章 程序控制结构-5

4.3 循环的特殊控制语句

功能
  • 在程序执行过程中,有时候需要提前跳出循环;或者在某种条件满足时,不执行循环体中的某些语句而立即从头开始新一循的循环,这时就用到了循环控制语句breakcontinuepass
  • 循环中断语句break:终止循环的执行
  • 循环短路语句continue:立即结束本次循环,开始下一轮循环
  • 空语句pass:不做任何事情,一般用作占位语句,保证程序结构的完整性
4.3 循环的特殊控制语句——break
  • 循环在某一轮执行到某一语句时,已经有了结果,不需要再继续循环,就用break语句跳出(中断)循环
  • 切记:循环条件为True,循环体中一定有break( 恒真循环while True:中间一定会有break
4.3 循环的特殊控制语句——continue
  • 循环短路continue:当在循环结构中遇到continue语句时,将程序跳过continue后面尚未执行的语句,重新开始下一轮循环。即只结束本次循环的执行,并不终止整个循环的执行
  • break语句使用较多,但continue语句实际使用次数并不多,这是因为continue语句常常是可以替代的
4.3 循环的特殊控制语句——pass
  • pass语句是空语句,不做任何操作,在特别时候一般用作占位语句,保证程序结构的完整。
4.3 循环的特殊控制语句——else
  • 无论是for循环还是while循环都支持else语句,具体格式如下:
for <变量> in <序列对象>:
  <循环体>
else:
  <语句块>
  
while <条件表达式>:
  <循环体>
else:
  <语句块>
  • 如果循环是从正常出口(即while后的条件表达False,或for语句遍历了所有序列对象)结束退出的,则执行else子句;若非正常迭代结束退出(如因执行了break语句而提前退出循环),则不执行else子句

第三章 程序控制结构-6

5 嵌套程序

无论是分支结构还是循环结构,都允许嵌套。嵌套就是分支内还有分支,循环内还有循环或者分支内有循环,循环内有分支等。
# 注意区别恒真循环
import random
num=random.randint(0,10)
x=eval(input("请输入一个数:"))
while True:
  if num==x:
    print("恭喜你猜对了!")
    break
  else:
    print("很遗憾,没有猜对哟!")
  x=eval(input("请输入一个数:"))
# *********
for j in range(1,10):
  print(" *", end="")

# 重复输出9行*号
for i in range(1,10):
  for j in range(1,10):
    print("*", end="")
  print( )
嵌套循环:在循环语句中包含另外一个完整循环语句

生活中嵌套循环的例子

# 钟表
for i in range(1,13):
  for j in range(1,60):
    ……
  ……

任务-输出九九乘法表

效果
1*1= 1
2*1= 2 2*2= 4
3*1= 3 3*2= 6 3*3= 9
4*1= 4 4*2= 8 4*3=12 4*4=16
5*1= 5 5*2=10 5*3=15 5*4=20 5*5=25
6*1= 6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1= 7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1= 8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
9*1= 9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81

问题分析
任务分解—步骤1
for i in range(1,10):
  for j in range(1,i+1):
    print(" *", end="")
  print( )
任务分解—步骤2
for i in range(1,10):
  for j in range(1, i+1):
    print(i,"*",j,"=",i*j,end=" ")
  print( )
for i in range(1,10):
  for j in range(1, i+1):
    if i*j>=10:
      print(str(i)+"*"+str(j)+"="+str(i*j),end=" ")
    else:
      print(str(i)+"*"+str(j)+"="+" "+str(i*j),end=" ")
  print( )
for i in range(1,10):
  for j in range(1, i+1):
    print(" {}*{}={:<2d}". format.(i,j,i*j), end="")
  print( )

嵌套循环小结

1 嵌套循环的一般结构如下
while 条件表达式1:
  while 条件表达式2:
    语句序列2
  语句序列1

while 条件表达式1:
  for 变量 in 序列对象:
    语句序列2
  语句序列1

for 变量1 in 序列对象1:
  for 变量2 in  序列对象2:
    语句序列2
  语句序列1
  
for 变量1 in 序列对象:
  while 条件表达式:
    语句序列2
  语句序列1
2 每一层循环在逻辑上必须是完整的
3 嵌套的内外循环控制变量不应同名

课后扩展练习

分别输出如图所示的图形
图一
*****
 *****
  *****
   *****
    *****
图二
*****
 ****
  ***
   **
    *
图三
  *
 ***
*****
#图一
for i in range(1,6):
  for z in range(i):
    print(" ",end="")
  for j in range(1,6):
    print ("*",end="")
  print()

#图二
for i in range(1,6):
  for z in range(0,i):
    print(" ",end="")
  for j in range(5,i-1,-1):
    print ("*",end="")
  print()

#图三
for i in range(1,6,2)
  for z in range(1,int((5-i)/2)+1):
    print ("*",end="")
  for j in range(1,i+1):
    print ("*",end="")
  print()

第四章 序列-1

4.1 序列概述

4.2 字符串

4.3 列表

4.4 元组

4.1序列概述

  • Python中,根据容器的存储特点,操作方式,容器可以分为不同的类型,其中序列就是其中的一种内置的容器

  • 序列包括字符串,列表和元组

  • 序列类型的元素间存在顺序关系,各具体类型使用相同的索引体系,即正向索引和反向索引

  • 序列对象是可迭代的

  • 序列元素的索引

    ​ 反向从右侧索引-1开始,索引值递减

    ​ ←————————————————————————————————————

    索引-5-4-3-2-1
    1002.56“Python”[‘a’,‘b’](10,20)
    索引01234

    ​ ————————————————————————————————————→

    ​ 正向从左侧索引0开始,索引值递增

操作符或函数描述
x in s如果x是s的元素,返回True;否则返回False
x not in s如果x不是s的元素,返回True;否则返回False
s+t连接s和t,使之成为一个序列
s*n或n*s将序列s复制n次
s[i]返回序列的索引为i的元素
s[i:j:k]返回包含序列s索引为i到索引为j(不包括j)以k为步长的子序列
len(s)序列s的元素个数(长度)
min(s)序列s中的最小元素
max(s)序列s中的最大元素
s.index(x)序列s中第一次出现元素x的位置
s.count(x)序列s中出现x的总次数
all(s)判定给定的序列类型s,如果s中的所有元素都是True,则返回True,否则返回False
any(s)只要序列类型中任何一个元素是True,则返回True;若全部元素都是False,则返回False

需要注意,整数0,空字符串"",空列表[]等都被当作False

4.2 字符串

再识字符串

  • 定界符
  • 转义字符

字符串基本操作

  • 索引与切片
  • 运算符
  • 内置函数
  • 常用方法

字符串特殊应用

  • 字符串格式化

再识字符串

定义符
  • 字符串是一组不可变且有序的序列,其主要是用来表示文本信息。
  • 可以使用单引号、双引号、三引号(三个单引号或三个双引号)作为定界符对字符串进行定义。
>>> print('''蒹葭苍苍,白露为霜。
所谓伊人,在水一方。
溯洄从之,道阻且长。
溯游从之,宛在水中央。''')
> 输出效果
蒹葭苍苍,白露为霜。
所谓伊人,在水一方。
溯洄从之,道阻且长。
溯游从之,宛在水中央。
转义字符(特殊字符串)

思考如何输出?
I’m Mary
D:\one\two\tree\now

正确用法

>>> print("I'm Mary")
>>> print('I\'m Mary')
>>> print("D:\\one\\two\\tree\\now")
  • 转义字符是指在字符串中的某些特定的符号前加一个反斜杠之后,该字符将被解释为另外一种含义。
  • 如:print(‘I’m eva.’)
    | 转义 | 描述 | 转义 | 描述 |
    | :— | -------------- | ----- | --------------------------- |
    | \ | 在行尾的续行符 | \t | 水平制表符 |
    | \’ | 单引号 | \a | 响铃 |
    | \" | 双引号 | \b | 退格(Backspace) |
    | \0 | 空 | \\ | 反斜线 |
    | \n | 换行符 | \0dd | 八进制数,如\012代表换行 |
    | \r | 回车符 | \xhh | 十六进制数,如\x0a代表换行 |
字符串表示小结

(1)

 print('Hello Python!')
 print("Hello World!")

(2)

>>> print('''蒹葭萋萋,白露未晞。
所谓伊人,在水之湄。''')
>>> print("""溯洄从之,道阻且跻。
溯游从之,宛在水中坻。""")

(3)

print('Let\'s go')
print("d:\\abc\\123")

字符串基本操作

字符串索引
正向索引01234
反向索引-5-4-3-2-1

格式: <字符串或字符串变量>[索引]

>>> "温故而知新"[0]
'温'
>>> s1= "温故而知新"
>>> s1[3]
'知'
>>> s1[5]
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
str1[4]
IndexError: string index out of range
>>> "温故而知新"[-5] 
'温'
>>> s1= "温故而知新"
>>> s1[-2]
'知'
>>> s1[-6]
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
str1[-6]
IndexError: string index out of range
字符串切片

格式:<字符串或字符串变量>[start:end:step]

>>> s1= "温故而知新"
>>> s1[0:4:1]
'温故而知'
>>> s1[0:4:2]
'温而'
>>> s1= "温故而知新"
>>>print( s1[0:4:1])
温故而知
>>> print(s1[0:4:2])
温而
# 注意结果在形式上的区别
s1= "温故而知新"
#切片1 正着数
>>> s1[0:4]   #返回'温故而知's
# 切片2 负着数
>>> s1[-5:-3] #返回'温故's
# 切片3 省略数
>>> s1[:]  #返回'温故而知新'
>>> s1[1:]#返回'故而知新'
>>> s1[:-3]  #返回'温故's
# 切片4 跳着数
>>> s1[::2] #返回'温而新'
>>> s1[1:6:2]#返回'故知'
>>> s1[::-2]#返回'新而温'
字符串运算符
拼接运算符
>>> "温故而知新,"+ " 可以为师矣"
'温度而知新,可以为师矣'
>>> s1="中国女排"
>>> s2="夺冠"
>>> s3,s4=11,"连胜"
>>> print(s1+s2)
中国女排夺冠
>>> print(s1+str(s3)+s4+s2)
中国女排11连胜夺冠
复制运算符
>>> "Go"*3   #将返回由3个'Go'组成的新字符串
'GoGoGo '
>>>3*"Go"
'GoGoGo '
成员运算符
>>> "Python" in "I love Python"
True
>>> "Java " not  in " I love Python "
True
关系运算符

(1)单字符字符串的比较

>>>  "a">"A"   #返回 True
True
>>>  "0">"1"  #返回False
False

(2)多字符字符串的比较

>>> "Hello World!" >"Hello Python!"  
True
>>>"hello"<"hello world!"   
True
>>> ""<"a"   
True
字符串内置函数
  • 字符串函数操作是以字符串作为输入条件,经过处理后返回相应的值。
  • Python解释器提供了常见的字符串处理相关的内置函数,其调用形式为:<函数名> (<参数>)
    在此处插入表格
  • Unicode编码
  • Python 3以Unicode字符 为计数基础,中英文字符 及标点字符 都是1个长度单位。
  • Unicode又称万国码,是计算机科学领域里的一项业界标准,包括字符集、编码方案等,Python字符串中每个字符 都使用Unicode编码表示。
  • ord(s) 返回单个字符表示的Unicode编码
  • chr(x) 返回Unicode编码对应的单个字符

【试一试】 读程序,写出程序的功能

#加密小助手
words=input("请输入一句话:")
new_words=""
for w in words:
  new_words+=chr(ord(w)+1)
print("new_words:",new_words)

程序运行结果
请输入一句话:I love 中国
new_words: J!mpwf!丮图

【试一试】 编写程序,输入一个字符串,将其中的小写英文字母变为它的下三个字母,即a变成d,b变成e,……,z变成c,其它字符变为它的下一个字符。

words=input("请输入一句话:")
new_words=""
for w in words:
  if "a"<=w<"x":
   new_words+=chr(ord(w)+3)
 elif w=="x":
   new_words+="a"
 elif w=="y":
   new_words+="b"
 elif w=="z":
   new_words+="c"
 else:new_words+=chr(ord(w)+1)
print("new_words:",new_words)

程序运行结果
请输入一句话:我喜欢 Python
new_words: 戒喝欣!Qbwkrq

【例4-1】 凯撒密码

明文 密文
DOT GRW
DOTY GRWB
如果原文字符是P,其密文字符C,满足如下条件:
加密:C=(P+3)mod 26
解密:P=(C-3) mod 26

#凯撒密码加密.py
plaintext=input("请输入明文:")
for p in plaintext.lower():  #将明文转换成小写字符,遍历每一个字符
  if "a"<=p<="z":
    print(chr((ord(p)+3-ord("a"))%26+ord("a")),end="")
  else:
    print(p,end='')
字符串的常用方法
  • 字符串方法是对字符串进行处理的一个过程,由方法名和用圆括号括起来的参数列表组成。
  • Python中,字符串对象有大量自己特定的方法,可用于查找、检测、排版、替换等操作。
  • 字符串内置方法众多,根据功能不同,把常用方法从转换、判断、填充、查找、连接与分割等几个方面分类介绍。

格式:<字符串或字符串变量>.<方法名>([<参数1,参数2….>] )

【1】转换方法
方法例子描述
uppers.upper()‘MY NAME IS EVA’全部字符大写
lowers.lower()‘my name is eva’全部字符小写
swapcases.swapcase()‘mY NAME IS eVA’字符大小写互换
capitalizes.capitalize()‘My name is eva’串首字母大写,其余小写
titles.title()‘My Name Is Eva’单词首字母大写,其余小写
>>> s1="A journey of a thousand miles begins with single step."
>>> s1.upper()  #将全部字符转换为大写
'A JOURNEY OF A THOUSAND MILES BEGINS WITH SINGLE STEP.'
>>> s1.lower() #将全部字符转换为小写
'a journey of a thousand miles begins with single step.'
>>> s1.title() #所有单词首字母大写,其余小写
'A Journey Of A Thousand Miles Begins With Single Step.'
>>> s1.capitalize()   #将字符串的第一个字符转换为大写字符,其余小写
'A journey of a thousand miles begins with single step.'
>>> s1.swapcase()#将字符串中大小写字符互换
'a JOURNEY OF A THOUSAND MILES BEGINS WITH SINGLE STEP.'
【2】判断方法
方法例子描述
isalnums.isalnum()True全是字母或数字,返回True
isalphas.isalpha()False全是字母,返回True
isdigits.isdigit()False全是数字,返回True
islowers.islower()True有区分大小写字符,且全是小写,返回True
isuppers.isupper()False有区分大小写字符,且全是大写,返回True
istitles.istitle()False首字母为大写字母,返回True
isspaces.isspace()False全是空白字符,返回True
isprintables.isprintable()True全是可打印字符,返回True
>>> "你好JACK!".isupper( )  #判断字符串中所有的字母是否都为大写
True
>>> "你好JACK!".islower( )  #判断字符串中所有的字母是否都为小写
False
>>>  "你好JACK!".isalpha()  #判断一个字符串是否只包含字母或汉字,如果是返回True,否则返回False.
False
>>> "10086".isdigit()   #判断一个字符串是否只包含数字
True
>>> "中国移动10086".isalnum( )   # 判断一个字符串是否全部由字母、汉字或数字组成
True
>>>  "China Mobile".istitle()  #判断字符串中的所有单词是否都是首字母大写
True
【3】查找方法

S=“123,abc,123,abc”

方法例子结果描述
finds.find(“123”,1,7)
s.find(“ab”)
-1
4
范围内查找子串,返回首次出现位置,找不着返回-1
rfinds.rfind(“23”,1,13)
s.rfind(“123”)
9
12
范围内查找子串,返回末次出现位置,找不着返回-1
indexs.index(“123”,1,7)
s.index(“123”)
出错
0
范围内查找子串,返回首次出现位置,找不着报错
counts.count(",")
s.count(“234”)
3
0
返回子字符串在字符串中出现的次数
replaces.replace(“123”,“456”)
s.replace(“a”,“4”,1)
‘456,abc,456,abc’
‘123,4bc,123,abc’
查找子串并在次数范围内用制定字符串替代,返回新串
startswiths.startwith(“12”)
s.startwith(“12”,9)
True
False
如果范围字符串以指定子串开始,返回True
endswiths.endswith(“3”,1,11)
s.endwith(“23”)
True
False
如果范围字符串以指定子串结束,返回True
s1="A journey of a thousand miles begins with single step."
>>> s1.count("th")  #返回子串"th"在字符串s1中指定的区间内出现的次数
2
>>> s1.count("th",10,20) #返回子串"th"在字符串s1的索引序号10到20(不包括)间出现的次数
1
s1="A journey of a thousand miles begins with single step."
>>>  s1.find("th")#在s1中查找子串"th",返回第一次出现"th"的索引序号
15
>>>  s1.find("th",10,35)#在指定的区间内查找子串"th",返回"th"首次出现的索引序号
15
>>> s1.find("our",9,20) #在指定的范围内查找子串"our",若没有找到子串,返回-1.
-1
s1="A journey of a thousand miles begins with single step."
>>> s1.index("our")#在s1中查找子串"our",返回第一次出现"our"的索引序号
3
>>>  s1.index("our",9,20)   #在指定的范围内查找子串"our",若没找到会产生异常
Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
s1.index("our",9,20)
ValueError: substring not found
s1="A journey of a thousand miles begins with single step."
>>>  s1.strartswith("A")  #返回字符串s1是否以"A"开头
True
>>>   s1.startswith("our",9,20) #在索引区间[9,20] 内的子串若以our开头,则返回True,否则返回False
False
>>>  s1.endswith("our",0,6) #在指定区间内的子串若以our结尾,则返回True,否则返回False
True
>>>  s2="aabbaaccaa"
>>> s2.replace("aa","#") #将s2中所有的子串"aa" 替换为"#"
'#bb#cc#'
>>> s2.replace("aa","#",2)  #将s2中前两个子串"aa" 替换为"#"
'#bb#ccaa'

【4】连接与分割方法

方法描述
join用指定字符连接字符串或列表
split以指定字符为分割符,分割成多个字符串,返回包含分割结果的列表
>>>  "-".join("1234")   #用"-"连接字符串"1234"
'1-2-3-4'
>>> ".".join(["www" ,"lnu", "edu","cn"])   #用"."连接列表中的字符串
'www.lnu.edu.cn'
>>> "abc123@163.com".split("@")  #以指定字符@作为分隔符,返回包含分
['abc123', '163.com']   割结果的列表
>>>  "www.sohu.com".split(".") 
['www', 'sohu', 'com']
>>> "www.sohu.com".split(".",1)  #将字符串以.作为分隔符,分割1次
['www', 'sohu.com']
>>>  "www.sohu.com".split(".",2)
['www', 'sohu', 'com']
#若没有指定分隔符,将以空白字符(空格,\n,\r,\t)分割字符串
>>> "A journey of a thousand miles begins with single step".split()
 ['A', 'journey', 'of', 'a', 'thousand', 'miles', 'begins', 'with', 'single', 'step']
>>>  "hello\nworld!".split()
 ['hello', 'world!']

【5】修剪(格式)方法
S=“123,abc,123,abc”

方法描述
center返回指定长度的居中对齐字符串副本
ljust返回指定长度的左对齐字符串副本
rjust返回指定长度的右对齐字符串副本
zfill返回指定宽度字符串不足左侧用0补位
strip删除两边空白字符或指定字符
lstrip删除左边空白字符或指定字符
rstrip删除右边空白字符或指定字符
>>> "abc hello ab".strip("ab")  #删除字符串两边的子串"ab"
'c hello '
>>>  "  abc  123  ".strip()   #删除字符串两边的空白字符(空格)
'abc  123'
>>> "\nabc hello ab\n\r".strip()#删除字符串两边的空白字符(\n,\r)
'abc hello ab'

字符串特殊应用

字符串的格式化—format方法

输出的格式:
你好,____,你得到了____分

输出的内容:
你好,张小小,你得到了_95_分
你好,李云鹏,你得到了_120_分
你好,陈山山,你得到了_215_分

格式:<模板字符串>.format(<参数1,参数2……>)

>>> "my {} is {}".format("name","eva")
  • format( )方法可以有一个或多个类型不同的对象参数。
  • format( )方法执行时,首先进行对象参数与模板字段项的匹配,然后将每个对象参数,按照所匹配的模板字段指定格式转换为字符串,并替换所匹配的模板,返回一个被替换后的字符串。
# { }—位置匹配,不带序号,按顺序填充
>>> print("name is {},id is{}".format("王小瞳","190101"))
name is 王小瞳,id is 190101
# {0},{1}—序号匹配,可调换顺序
>>> print("name is {0},id is{1}".format("王小瞳","190101"))
name is 王小瞳,id is 190101
>>> print("name is {1},id is{0},{1}是计算机专业的学生".format("190101","王小瞳"))
name is 王小瞳,id is 190101,王小瞳是计算机专业的学生
# {name}、{id}—名称匹配,带关键字填充
>>> print("name is {name},id is{id}".format(name="王小瞳",id="190101"))
name is 王小瞳,id is 190101
# {0[0]},{0[1]}—索引下标匹配
>>> print("name is {0[0]},id is{0[1]}".format(["王小瞳","190101"]))
name is 王小瞳,id is190101
  • 使用format方法时,在{ }内除了包含参数或参数序号外,还可以包含格式控制信息,用来控制参数显示时的格式,二者中间用冒号隔开。
    格式:{[<参数>|<参数序号>]: <格式控制标记>}
>>> print("我爱你,{:>4}".format("中国"))
我爱你,  中国
>>> print("{0},{0:^4},壮丽的{1:>3}".format("中国","山河"))
中国, 中国 ,壮丽的  山河

{[<参数>|<参数序号>]: <格式控制标记>}

:<填充><对齐><宽度><,><精度><类型>
引导符号用于填充的单个字符,默认为空格<左对齐
>右对齐
^居中对齐
设置输出宽度数字的千位分隔符,适用于整数和浮点数浮点数小数部分的精度或字符串的最大输出长度整数类型b.c.d.e.x.X
浮点数类型e.E.f.%
>>> print("name is {},id is {:#>8},score is {:>5.1f}".format("王小瞳","190101",98.69))
name is 王小瞳,id is ##190101,score is 98.7
format方法的优势

(1)无需理会填充数据的数据类型问题
(2)单个参数可以多次输出,参数顺序可以不相同
(3)填充方式十分灵活,对齐方式十分强大

【例4-2】下面输出的是前三名同学的成绩排名

#E4-2.py
print("{0:*^30}".format("score ranking"))
print("{0:<5}{1:^20}{2:>5}".format("id","name","score"))
print("{0:<5}{1:^20}{2:>5}".format(1,"eva",100))
print("{0:<5}{1:^20}{2:>5}".format(2,"coco",98))
print("{0:<5}{1:^20}{2:>5}".format(3,"fanny",95))

程序的运行结果为:
score ranking*
id name score
1 eva 100
2 coco 98
3 fanny 95

第四章 序列-2

4.3 列表3

初识列表

  • 列表的创建
  • 访问列表元素与切片

列表的遍历

  • 直接遍历
  • 利用索引遍历
  • 利用枚举遍历

列表的常用方法

  • 增加元素
  • 删除
  • 排序
  • 复制列表

列表的常用统计与计算函数

  • 统计函数
  • 计算函数

初识列表

列表(list)是包含0个或多个对象引用的有序序列,并且是Python中内置的可变序列,它提供了灵活多变的数据存储方案。

>>> favourite_fruits=["apple", "banana","pear","peach"]
>>> luck_numbers=[7,3,12,36,[9,11]]
>>> friends=["王芳",18, "李想",17, "张小若",19]
>>> ['p','y','t','h','o','n']
列表的创建
>>> list1=[ ]   #创建空列表
>>> list2=[98,80,75,90,65,82]  #创建数值元素的列表
>>> ["hello","world","!"]#创建包含字符串元素的列表
>>> list3=[x for x in range(5)]   #列表解析创建列表[0, 1, 2, 3, 4]
# 用list( )函数将其他类型数据转换为列表
>>> list4=list(range(10, 20, 2))   #转换后的列表为[10, 12, 14, 16, 18]
>>> list5=list("Python")#转换后的列表为['p', 'y', 't', 'h', 'o', 'n']
>>> list6=list(('h', 'e', 'l', 'l', 'o'))  #转换后的列表为['h', 'e', 'l', 'l', 'o']
访问列表元素与列表切片
>>> animals=["cat","dog","monkey","horse","spider","frog"]
>>> animals[0] 
'cat'
>>> animals[len(animals)-1]  
' frog '
正向索引012345
“cat”“dog”“monkey”“horse”“spider”“frog”
反向索引-6-5-4-3-2-1
>>> animals=["cat","dog","monkey","horse","spider","frog"]
>>> animals[3:]  #返回列表中索引值为3到最后一个元素的所有
元素组成的列表
['horse', 'spider', 'frog']
>>> animals[1:3]  #返回列表中索引值为1到索引值为3(不包含)的元素组成的列表
 ['dog', 'monkey']
>>> animals[:]   # 返回原列表的副本
['cat', 'dog', 'monkey', 'horse', 'spider', 'frog']
>>> animals=["cat","dog","monkey","horse","spider","frog"]
>>> animals[-1]  #返回列表中索引为-1的元素
'frog'
>>> animals[-6:-3] #返回列表中前三个元素组成的新列表
['cat', 'dog', 'monkey']
# 嵌套列表
>>> list1=[['张小小',20],['王小瞳',19],['李焕',18]]
>>> list1[1] 
['王小瞳', 19]
>>>  list1[1][0]
'王小瞳'
>>> list1[0:2]
[['张小小', 20], ['王小瞳', 19]]
>>> list1[1][:]
['王小瞳', 19]

列表的遍历

任务:将中国的四大名著的书名存储在一个列表中,再遍历列表将四大名著的书名打印出来。

【1】 直接遍历列表元素

格式:

for <元素(变量)> in <列表>:
  print(<元素(变量)>)
novels=['西游记','水浒','三国演义','红楼梦']
for item in novels:
  print(item)

运行结果
西游记
水浒
三国演义
红楼梦

【2】 利用索引遍历列表元素

格式:

for <索引> in  range(<列表长度>):
  print(<列表[索引]>)
novels=['西游记','水浒','三国演义','红楼梦']
for i in range(len(novels)):
  print(novels[i])

运行结果
西游记
水浒
三国演义
红楼梦

【3】 利用枚举遍历列表的索引和对应的元素
for <索引值> ,<元素> in enumerate(<列表>):
  print(<索引值>,<元素>)
novels=['西游记','水浒','三国演义','红楼梦']
for i , item in enumerate(novels):
  print(i,item)

运行结果
0 西游记
1 水浒
2 三国演义
3 红楼梦

【4】 列表解析

格式:

[<表达式> for <列表中元素1> in <可迭代对象1>
   for <列表中元素2> in <可迭代对象2>
 …
   for <列表中元素n> in <可迭代对象n>
   if <条件表达式>]
>>> a=[ ]
>>> for i in range(11):
>>> if i%2==0:
>>> a.append(i)
>>> a
[0, 2, 4, 6, 8, 10]
#代码优化
>>> a=[i for i in range(11) if i%2==0]
>>> a
[0, 2, 4, 6, 8, 10]
>>> [x for x in range(20)] 
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]
>>> [x **2 for x in range(10) if x%2==0]
[0,4,16,36,64]
>>> [x+y for x in range(3) for y in range(3)]
[0, 1, 2, 1, 2, 3, 2, 3, 4]

>>> word = "solidarity"
>>> vowels = "aeiou"
>>> [i for i in word if i in vowels]
['o', 'i', 'a', 'i']

列表的常用方法

【1】向列表增加元素
#(1) list1.append(x) 在列表list1末尾增加一个元素x
>>> list1=[1,2,3]
>>> list1.append(4) 
>>> list1
[1,2,3,4]
>>> list1.append(["a","b"])
>>> list1
[1,2,3,4,['a','b']]
#(2) list1.extend(list2) 在列表list1末尾增加列表list2中的元素
>>> list1=[1,2,3]
>>> list1.extend([4])
>>> list1
[1,2,3,4]
>>> list1. extend(["a","b"])
>>> list1
[1,2,3,4,'a','b']
#(3) list1.insert(i,x) 在列表list1索引为i的位置增加元素x
>>> list1=[1,2,3]
>>> list1.insert(3,4)
>>> list1
[1,2,3,4]

【试一试】向列表增加元素

>>> novels,nove1s1=["西游记","吴承恩"],["水浒","施耐庵"]
>>> novels2,novels3=["三国演义","罗贯中"],["红梦梦","曹雪芹"]
>>> novels.append(novels1)
>>> novels
['西游记', '吴承恩', ['水浒', '施耐庵']]
>>> novels.extend(novels2)
>>> novels
['西游记', '吴承恩', ['水浒', '施耐庵'], '三国演义', '罗贯中']
>>> novels.insert(0,novels3)
>>> novels
[['红梦梦', '曹雪芹'], '西游记', '吴承恩', ['水浒', '施耐庵'], '三国演义', '罗贯中']
【2】列表的删除

list1=[0,1,2,3,4,5,6,7,8,9]

#(1) del list1[i]	删除列表list1的索
引为i位置的元素
>>> del list1[0]
>>> list1
[1, 2, 3, 4, 5, 6, 7, 8, 9]
#(2) del list1[i:j:k]	删除列表list1第i到第j(不包括j)索引位置以K为步长的元素
>>> del list1[0:8:2]
>>> list1
[1,3,5,7,9]

list1=[0,1,2,3,4,5,6,7,8,9,4]

#(3) list1.remove(x)  删除列表list1中出现的第一个x元素
>>> list1.remove(4)
>>> list1
[0, 1, 2, 3, 5, 6, 7, 8, 9,4]
#(4) list1.clear( )	删除列表list1中的所有元素
>>> list1.clear()
>>> list1
[ ]

list1=[0,1,2,3,4]

#(5) list1.pop(i) 返回列表list1 中索引为i位置的元素并删除该元素
  list1.pop( )  返回列表list1中最后一个元素并删除该元素
>>> list1.pop(2)
2
>>> list1
[0,1,3,4]
>>> list1.pop()
4
>>> list1
[0,1,3]
【3】列表的排序
#(1)list1.reverse( )   将列表list1中的元素反转
>>>list1=["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"]
>>> list1.reverse()
>>> list1
['Sunday', 'Saturday', 'Friday', 'Thursday', 'Wednesday', 'Tuesday', 'Monday']
#(2) list1.sort(key=None,reverse=False )  若省略参数,对列表list1中的元素按升序排序;若参数reverse=True,则按降序排序;key指定排序规则
>>> list1.sort()
>>> list1
['Friday', 'Monday', 'Saturday', 'Sunday', 'Thursday', 'Tuesday', 'Wednesday']
>>> list1.sort(reverse=True)
>>> list1
['Wednesday', 'Tuesday', 'Thursday', 'Sunday', 'Saturday', 'Monday', 'Friday']
>>> list1.sort(key=len)
>>> list1
['Friday', 'Monday', 'Sunday', 'Tuesday', 'Saturday', 'Thursday', 'Wednesday']
【4】列表的复制
#list1.copy( )复制生成一个包括list1中所有元素的新列表
>>> list1=[1,2,3,4]
>>> list3=list1
>>> list2=list1.copy( )
>>> list1
[1, 2, 3, 4]
>>> list2
[1,2,3,4]
>>> list3
[1,2,3,4]
>>> id(list1)
53290824
>>> id(list2)
53285704
>>> id(list3)
53290824
>>> list1=[1,2,3,4]
>>> list3=list1
>>> list2=list1.copy( )

有助于深入理解列表的存储机制
id:53290824
list1 → 11002301 → 1 ← 11002301 ← list2
list3 → 11452323 → 2 ← 11452323
29452324 → 3 ← 29452324
36457423 → 4 ← 36457423

【例4-3】定义一个保存世界人口数量前六位国家的列表,在列表末尾增加尼日利亚、孟加拉国、俄罗斯和墨西哥,使其显示世界人口排名前十的国家。然后将墨西哥从列表中删除,并将列表的国家按人口数量的升序显示

#E4-3.py
country=['中国','印度','美国','印度尼西亚','巴西','巴基斯坦']
country.extend(['尼日利亚','孟加拉国','俄罗斯','墨西哥'])   
country.pop( )
country.reverse( )
print(country)

运行结果
[‘俄罗斯’, ‘孟加拉国’, ‘尼日利亚’, ‘巴基斯坦’, ‘巴西’, ‘印度尼西亚’, ‘美国’, ‘印度’, ‘中国’]

【试一试】从键盘任意输入8个英文单词,将其中以非元音字母开头的单词放入列表中,最后输出列表

#方法1

s="aeiou"
ls=[ ]
for i  in  range(8):
  words=input("请输入一个单词:")
  if words.lower( )[0]  not in s:
    ls.append(words)
print("非元音开头的单词有:",ls)

运行结果
请输入一个单词:hello
请输入一个单词:exclent
请输入一个单词:hard
请输入一个单词:work
请输入一个单词:our
请输入一个单词:bee
请输入一个单词:an
请输入一个单词:good
非元音开头的单词有: [‘hello’, ‘hard’, ‘work’, ‘bee’, ‘good’]

#方法2
s="aeiouAEIOU"
ls=[ ]
for i  in  range(8):
  words=input("请输入一个单词:")
  if words[0]  not in s:
 ls.append(words)
print("非元音开头的单词有:",ls)

运行结果
请输入一个单词:hello
请输入一个单词:exclent
请输入一个单词:hard
请输入一个单词:work
请输入一个单词:our
请输入一个单词:bee
请输入一个单词:an
请输入一个单词:good
非元音开头的单词有: [‘hello’, ‘hard’, ‘work’, ‘bee’, ‘good’]

列表的统计与计算函数

若 list1=[2,4,6,8,10,2]

#(1) list1.count(x)返回元素x在列表list1中的出现次数
>>> list1.count(2)
2
#(2) list1.index(x)	返回元素x在列表list1中首次出现的索引位置
>>> list1.index(2)
0
#(3) sum(list1)	统计数值列表list1中各元素的和
>>> sum(list1)
3232
若  list1=[2,4,6,8,10,2]
#(4) len(list1)	返回列表list1的长度
>>> len(list1)
6
#(5) max(list1)	返回列表list1中元素的最大值
>>> max(list1)
10
#(6) min(list1)	返回列表list1中元素的最小值
>>> min(list1)
2

【例4-4】 新建程序文件E4-4.py,定义一个保存10名学生计算机课成绩的列表,统计出10名学生的平均成绩,并统计得100分的人数。

#E4-4.py
sc=[90,78,100,92,86,100,79,83,62,93]
print("平均成绩为:")
print(sum(sc)/len(sc))
print("得100分的人数为:")
print(sc.count(100))

运行结果
平均成绩为:
86.3
得100分的人数为:
234

【试一试】 读程序,分析程序的运行结果

from random import *
num=eval(input("请输入一个大于等于3的数"))
listRand=[ ]
for i in range(num):
  rand=round(uniform(0,100),2)
  listRand.append(rand)
print(listRand)
print(choice(listRand))   #从列表中随机返回一个元素
print(sample(listRand,2)) #从列表中随机返回由2个元素组成的列表
print(max(listRand))35

4.4元组及元组操作

  • 元组(tuple)是Python中另一个重要的序列结构,它是包含 0 个或多个元素的不可变序列类型。
  • 在形式上,元组的所有元素通常放在一对"( )“中,两个相邻元素间使用”,"分隔。例如:
    tuple1=(10,20,30)tuple1=10,20,30 省略()

【1】 创建元组37

>>>num=(2,6,8,12,35,68,96)   
>>>poets=('李白','杜甫','白居易','王维','苏轼') 
>>>tup=(("屠呦呦",85),["诺贝尔奖","青蒿素"])
>>>name=("Mary",)
>>>t1=tuple(range(1,10,2)) 
>>> t1
(1,3,5,7,9)
>>>t2=tuple("hello")
>>> t2
('h', 'e', 'l', 'l', 'o')

【2】 元组的访问4.3

>>>poets=('李白','杜甫','白居易','王维','苏轼')
>>> poets[1]="孟浩然"   #元组不可更改其中的元素   
TypeError: 'tuple' object does not support item assignment
>>> poets([0])  #返回元组中第0个元素的值
'李白'
>>> poets[1:3]  #元组切片
('杜甫', '白居易')
>>> tup2=num+name   #元组相加(相连)后返回一个 新的元组
(2,6,8,12,35,68,96, "Mary")

【3】 删除元组

>>> del tup2   #删除元组tup2
>>> tup2
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
tup2
NameError: name 'tup2' is not defined

【4】 元组的其他操作

>>> tup3=(10,20,30,40,50)
>>> sum(tup3)
150
>>> max(tup3)
50
>>> min(tup3)
10
>>> len(tup3)
5
>>> 20 in tup3
True
>>> 60 not in tup3
True
>>> tup3.index(30)
2
>>> tup3.count(10)
1

【5】 元组与列表的区别

(1)列表属于可变序列,它的元素可以随时修改或者删除;元组属于不可变序列,其中的元素不可以修改。
(2)列表可以使用append( )、extend( )、insert( )、remove( )和pop( )等方法实现添加和修改列表元素,而元组没有这几个方法,所以不能向元组中添加、修改或删除元素。
(3)元组比列表的访问和处理速度快,所以当只需要对其中的元素进行访问,而不进行任何修改时,建议使用元组。
(4)列表不能作为字典的键,而元组则可以。

第五章 字典和集合

5.1 集合

5.2 字典

5.1 集合

  • 集合(set)是一组对象的组合,是一个不重复的、无序的数据集合体。
  • 类似数学中的集合,即包含0个或多个数据项的无序组合。可以进行交、并、差等运算。
  • 集合用"{}"表示,因为是无序组合,它没有索引和位置的概念,集合中的元素可以动态增加或删除
  • 可变集合元素类型只能是不可变数据类型,如整数、浮点数、字符串、元组等,而列表、字典和集合类型本身都是可变数据类型,不能作为集合的元素出现
  • 由于集合元素是无序的,集合的输出顺序与定义顺序可以不一致
>>> {1,5,7}
{1, 5, 7}
>>> {1,4,2,5,4,2}
{1, 2, 4, 5}
>>> s={"abc",15,3.14,15}
>>> s
{'abc', 3.14, 15}
>>> type(s)
<class 'set'>
>>> 

1 创建集合

#(1)直接给变量赋值一个集合字面量
>>> fruits={"apple","orange","pear"}
>>> fruits
{'pear', 'apple', 'orange'}
#(2)使用set()创建一个空集合
>>> emps=set( )
#(3)使用set()将列表或元组转换成集合
>>> s1=set([2,4,6,8,10,8])
>>> s1
{8, 2, 10, 4, 6}
>>> s2=set("abc")
>>> s2
{'b', 'a', 'c'}
>>> type(s)
<class 'set'>

强调

  • 若emps={ } 将创建一个字典,而非创建一个集合
  • 创建集合时,Python会自动消除重复的值
  • 以上创建的为可变集合
#(4)创建不可变集合
>>> set3=frozenset('hello world')
>>> set3
frozenset({'l', 'w', ' ', 'e', 'd', 'r', 'h', 'o'})
>>> type(set3)
<class 'frozenset'>
>>> set4={1,2,'a',set3}
>>> set4
{1, 2, 'a', frozenset({'o', 'd', ' ', 'l', 'r', 'h', 'e', 'w'})

强调

  • frozenset( )函数可以将元组、列表和字符串等类型数据转换成不可变集

2 集合的常用操作函数或方法

若s1={2,3,“a”,(10,20)},s2={2,3,5,7,11}

函数或方法描述示例结果
len(s)返回集合中元素的数量len(s1)4
min(s)
max(s)
返回集合中所有能比较的元素中最小(最大)的元素min(s2)
max(s2)
2
11
sum(s)将集合元素求和sum(s2)28
s.add(x)若x不在集合中,将x增加到集合s中s2.add(13){2,3,5,7,11,13}
s.remove(x)
s.discard(x)
如果x在集合s中,移除该元素;否则会产生KeyError异常(没有任何操作)s1.remove(“a”)
s1.remove(8)
s1.discard(8)
{2,3,(10,20)}
keyError异常
无任何操作
s.clear()移除s中所有的元素s2.clear()set()

若s1={1,2,3,4},s2={1,2,3}

函数或方法描述示例结果
A.issubset(B)判断A是否是B的子集s1.issubset(s2)False
A.issuperset(B)判断A是否是B的超集s1.issupperset(s2)True
A.isdisjoint(B)判断A与B是否没有共同元素s1.isdisjoint(s2)False
A.union(B)返回A与B的并集s1.union(s2){1,2,3,4}
A.intersection(B)返回A与B的交集s1.intersection(s2){1,2,3}
A.difference(B)返回A与B的差集s1.difference(s2){4}
A.symmetric_difference(B)返回A与B的对称差集s1.symmetric_difference(s2){4}

3 集合的操作符

操作符及运算描述
A|BA与B的并集
A-BA与B的差集
A&BA与B的交集
A^BA与B的对称差集

强调

  • 集合的操作逻辑与数学定义相同
>>> s1={2,3,5,7,11}
>>> s2={2,3,4,5,6,7}
>>> s1|s2
{2, 3, 4, 5, 6, 7, 11}
>>> s1&s2
{2, 3, 5, 7}
>>> s1-s2  #出现在s1但不出现在s2的元素新集合
{11}
>>> s1^s2 #返回一个s1和s2中非共同元素组成的新集合
{4, 6, 11}
操作符及运算描述
A==B判断A与B是否相等
A!=B判断A与B是否不相等
A<B判断A是否是B的真子集
A<=B判断A是否是B的子集(包括非真子集)
A>B判断A是否是B的真超集
A>=B判断A是否是B的超集(包括非真超集)
C in AC是否是A的成员
C not in AC是否不是A的成员
>>> s1={2,3,5,7}
>>> s2={2,3,4,5,6,7,11}
>>> s1==s2
False
>>> s1<=s2
True
>>> s2>s1
True
>>> 3 in s1
True
>>> 8 not in s2
True

4 集合的遍历

用循环实现遍历集合中的各个元素

s={2,3,5,7,11}
for i in s:
  print(i)

程序运行结果
11
2
3
5
7

综合实例

【例5-1】 已知两个集合footballSet和basketballSet,分别存储选择了足球兴趣小组和篮球兴趣小组的学生姓名,请自行购建集合数据,计算并输出如下信息:
(1)选择了两个兴趣小组的学生姓名和人数
(2)仅选了一个兴趣小组的学生姓名和人数

#E5-1.py
footballSet={'Tom','Lily','Rose','Jack'}
basketballSet={'John','Tom','Jack','Mary','Frank'}
s1=footballSet&basketballSet
s2=footballSet^basketballSet
print(“选择两个兴趣小组的学生有{},共{}人.format(s1,len(s1)}
print(“仅选一个兴趣小组的学生有{},共{}人.format(s2,len(s2)}

程序运行结果
选择两个兴趣小组的学生有{‘Jack’, ‘Tom’},共2人
仅选一个兴趣小组的学生有{‘Rose’, ‘John’, ‘Lily’, ‘Frank’, ‘Mary’},共5人

【试一试】 读程序,分析程序的运行结果

#E5-0.py
mto=["cc","bbbb","afa","sss","bbbb","cc",'shafa']
ato=list(set(mto))
print(ato)
ato.sort(key=mto.index)  #按mto原索引顺序排序
print(ato)

运行结果
[‘bbbb’, ‘sss’, ‘cc’, ‘shafa’, ‘afa’]
[‘cc’, ‘bbbb’, ‘afa’, ‘sss’, ‘shafa’]

5.2 字典

字典
  • 字典(dict)是以"{}“为界限符,以”,"分隔的键值对的集合。
  • 字典的键值对之间无序。键相当于索引,它对应的值就是数据,通过键信息查找对应的值信息,这个过程叫映射
  • 字典内的键必须是唯一(不可重复)的,值可以是任意数据类型,且值可以重复
  • 字典中的键必须是不可变的数据类型,如整数、实数、字符串、元组等。不允许使用列表、集合、字典作为字典的键,因为这些类型的数据是可变的。
  • 格式:{<键1>:<值1>,<键2>:<值2>,……<键n>:<值n>}
>>> student={"190401301":"李佳原","190401302":"刘兴远","190401401":"张纯浩"}
>>> student
{'190401302': '刘兴远', '190401301': '李佳原', '190401401': '张纯浩'}

键值对之间没有顺序

字典与序列类型的区别
  • 存取和访问数据的方式不同。序列类型通过编号存取数据,而字典是根据键存取。
  • 序列类型是有序的数据集合,字典是无序的数据集合。字典中的键值对没有明确的顺序。
  • 字典是可变类型,序列类型的字符串、元组是不可变类型,列表是可变类类型。

1 创建字典

【1】 创建字典并赋值
>>> d={ }#创建空字典
>>> print(d)
{}
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1
{'Tom': 20, 'Alice': 20, 'Mary': 19, 'Rose': 18}
>>> type(d)   #返回d的数据类型
<class 'dict'>
>>> type(a1)
<class 'dict'>
【2】 用内建函数dict( )创建字典
>>>b1=dict( )#创建空字典
>>> b2
{}
>>> b2=dict(((1,"星期一"),(2,"星期二"),(3,"星期三"))) #以键值对形式的元组创建字典 
>>> b2
{1: '星期一', 2: '星期二', 3: '星期三'}
>>> b3=dict([(1,"星期一"),(2,"星期二"),(3,"星期三")]) #以键值对形式的列表创建字典 
>>> b3
{1: '星期一', 2: '星期二', 3: '星期三'}
>>> b4= dict(name='Allen', age=14, gender='male')   #以"键=值"方式建立字典,但键必须是字符串型
>>> b4
{'gender': 'male', 'age': 14, 'name': 'Allen'} 
【3】 用dict( )函数和zip( )函数创建字典

格式:
<字典名>=dict(zip(<序列1>,<序列2>))
用zip( )函数可以把两个序列(列表或元组)对应位置的元素做为一个键值对,生成一个字典

>>> d=dict(zip(["a","b","c"],[1,2,3]))
>>> d
{'a': 1, 'b': 2, 'c': 3} 
>>> d2=dict(zip(("姓名","年龄","性别"),("王小华",20,"女")))
>>> d2
{'性别': '女', '年龄': 20, '姓名': '王小华'}
【4】 用内建函数fromkeys( )创建字典

格式:
dict.fromkeys(seq[,value])
{}. fromkeys(seq[,value])
适用于创建一个所有值都相等的字典

>>> c={}.fromkeys((1,2,3),"student")   #指定所有键(1,2,3)对应的value值为"student"
>>> c
{1: 'student', 2: 'student', 3: 'student'}
>>> c=dict.fromkeys((1,2,3),"student")
>>> c
{1: 'student', 2: 'student', 3: 'student'}
>>> c=dict.fromkeys((1,2,3))#以给参数为键,但不指定value值,则创建value值为空的字典
>>> c
{1: None, 2: None, 3: None}

2 字典的基本操作

【1】 字典的访问
  • 用下标访问字典中的元素,下标是字典中的"键"
  • 格式:字典名[键名]<值>=字典名[键名]
  • 如果键在字典中,则返回该键对应的值,否则引发一个KeyError错误。
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1["Mary"]
19
>>> a1["Jack"]
Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
a1["Jack"]
KeyError: 'Jack'
【2】 字典元素的添加与修改
  • 字典没有预定义大小的限制,可以随时向字典添加新的键值对,或修改现有键 对应的值
  • 格式:字典名[键名]=<值>
  • 若该键在字典中存在,是对该键对应的值进行修改(更新)操作,如果该键不在字典中,则表示添加一个新的"键值对",也就是字典中添加了一个新元素
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1["Mary"]=22
>>> a1
{'Alice': 20, 'Rose': 18, 'Tom': 20, 'Mary': 22}
>>> a1["Frank"]=42
>>> a1
{'Alice': 20, 'Rose': 18, 'Frank': 42, 'Tom': 20, 'Mary': 22}
【3】 字典的判断
  • 用in或not in来判断某些键是否存在于字典中
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> "Tom" in  a1
True
【4】 字典的长度
  • 用len( )函数返回字典中键值对的数量
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> len(a1)
4
【5】 字典的删除
  • 字典的删除用del命令实现,包括删除字典和字典中的元素
  • 删除字典中的元素的命令为:del 字典名[键名]
  • 删除字典的命令为:del 字典名
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> del a1["Mary"]
>>> a1
{'Alice': 20, 'Rose': 18, 'Tom': 20}
>>> del a1
>>> a1
Traceback (most recent call last):
  File "<pyshell#27>", line 1, in <module>
a1
NameError: name 'a1' is not defined

2 字典的常用方法

  • 格式:<字典名>.<方法名>(<方法参数>)
操作方法描述(以字典名是d为例)
d.keys()返回所有的键信息
d.values()返回所有的值信息
d.items()返回所有的键值对
d.get(key,default)键存在则返回相应值,否则返回默认值
d.pop(key,default)键存在则返回相应值,同时删除键值对,否则返回默认值
d.popitem()随机从字典取出一个键值对,以元组(key,value)形式返回
d.update(d1)将d1中所有键值添加到当前字典d中,并覆盖同名键的值
d.setdefault(key[,value])如果字典中存在key,则返回key对应的值;若key不存在,则返回键值对key:value,同时把key:value添加到字典中,value的缺省值是None
d.clear()删除所有的键值对,清空字典
【1】 d.keys() 、d.values()与d.items()
  • 三个方法返回结果都是Python的一种内部数据类型 dict_keys,可以用list ( )、tuple( )函数将其转换为列表或元组
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1.keys( )
dict_keys(['Alice', 'Rose', 'Tom', 'Mary'])
>>> list(a1.keys( ))#将字典的键转化为列表
['Alice', 'Rose', 'Tom', 'Mary']
>>> a1.values( )
dict_values([20, 18, 20, 19])
>>> tuple(a1.values( ))   #将字典的值转化为元组
(20, 18, 20, 19)
>>> a1.items()
dict_items([('Alice', 20), ('Rose', 18), ('Tom', 20), ('Mary', 19)])
>>> list(a1.items( ))
[('Alice', 20), ('Rose', 18), ('Tom', 20), ('Mary', 19)]
【2】 d.get(key,default)
  • 根据键信息查找并返回值信息,如果Key存在则返回相应值,否则返回默认值
  • default可以省略,如果省略则默认值为空
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1.get("Alice")
20
>>> a1.get("Frank")
>>> a1.get("Frank","查无此人")
'查无此人'
【3】 d.pop(key,default)
  • 与get( )方法类似,根据键信息查找并返回值信息
  • 不同的是 pop( )在取出相应值后,将从字典中删除对应的键值对
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1.pop("Mary")
19
>>> a1
{'Alice': 20, 'Rose': 18, 'Tom': 20}
>>> a1.pop("Frank","查无此人")
'查无此人'
>>> a1
{'Alice': 20, 'Rose': 18, 'Tom': 20}
【4】 d.popitem( )
  • 随机从字典中取出一个键值对,以元组(key,value)形式返回
  • 取出后从字典中删除这个键值对
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1.popitem()
('Alice', 20)
>>> a1
{'Rose': 18, 'Tom': 20, 'Mary': 19}
【5】 d.update(d1 )
  • 将d1中所有键值添加到当前字典d中,并覆盖同名键的值
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a2={"John":28,"Mary":23}
>>> a1.update(a2)
>>> a1
{'Rose': 18, 'John': 28, 'Mary': 23, 'Alice': 20, 'Tom': 20}
【6】 d.clear( )
  • 删除所有的键值对,清空字典
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1.clear()
>>> a1
{}
【7】 d.setdefault(key[,value] )
  • 如果字典中存在key,则返回key对应的值;
  • 若key不存在,则返回键值对key:value,同时把key:value添加到字典中,value的缺省值是None
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1.setdefault("Mary")
19
>>> a1.setdefault("Frank",20)
20
>>> a1
{'Tom': 20, 'Rose': 18, 'Alice': 20, 'Mary': 19, 'Frank': 20}
>>> a1.setdefault("Lily")
>>> a1
{'Tom': 20, 'Mary': 19, 'Frank': 20, 'Rose': 18, 'Alice': 20, 'Lily': None,}

3 字典的遍历

  • 字典可以用for 循环对其元素进行遍历,其语法结构为:
for < 变量名> in <字典名>:
  <语句块>
  • for循环返回的变量名是字典的键,如果需要获得键对应的值,可以在语句块中通过get( )方法获得
a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18} 
for k in a1:
  print("name:{} and age:{}".format(k,a1.get(k)))

运行结果
name:Alice and age:20
name:Rose and age:18
name:Tom and age:20
name:Mary and age:19

综合实例

【例5-2】 编写程序,将一个字典的键和值对调
分析:

  • 对调就是将字典的键变为值,值变为键
  • 遍历字典,得到原字典的键和值,将原来的键作为值,原来的值作为键名,采用<字典名>[键名]=<值>方式,逐个添加字典元素
#E5-2.py
a={"a":1,"b":2,"c":3}
b={}
for k in a:
  b[a[k]]=k  #或 b[a.get(k)]=k
print(b)

运行结果
{1: ‘a’, 2: ‘b’, 3: ‘c’}

【例5-3】 编写程序,输入一串英文字符,单词之间用空格分隔开,统计其中单词出现的次数
分析:

  • 可采用字典数据结构来实现
  • 如果某个单出现在字典中,可以将单词(键)作为索引来访问它的值,并将它的关联值加1
  • 如果某个单词(键)不在字典中,使用赋值的方式创建键,并将它的关键值设为1
#E5-3.py
string=input("请输入一段英文字符:")
strList=string.split()
wordDict={}
for word in strList:
   if word in wordDict:
 wordDict[word]+=1
   else:
  wordDict[word]=1
print(wordDict)

运行结果
请输入一段英文字符:to be or not to be
{‘or’: 1, ‘not’: 1, ‘be’: 2, ‘to’: 2}

【扩展 例5-3】 编写程序,输入一串英文字符,单词之间用空格分隔开,统计其中单词出现的次数,并按降序输出词频

#E5-3-2.py
string=input("请输入一段英文字符:")
strList=string.split()
wordDict={}
for word in strList:
  if word in wordDict:
    wordDict[word]+=1
  else:
    wordDict[word]=1
items=list(wordDict.items())
items.sort(key=lambda x:x[1],reverse=True)
for i in range(len(items)):
  word,count=items[i]
print("{0:<10}{1:>5}".format(word,count))

运行结果
请输入一段英文字符:to be or not to be
to 2
be 2
or 1
not 1

课后思考

【 试一试】 已知有三位学生参加了主题演讲的记录列表:
names=[“Tom”,“Jack”,“Mary”,“Tom”,“Lily”,“Jack”,“Rose”],请统计出每个学生参加活动的次数并记录到字典中,结果如下(顺序不做要求):
{‘Tom’: 2, ‘Lily’: 1, ‘Mary’: 1, ‘Jack’: 2, ‘Rose’: 1}

#E5-4.py
names=["Tom","Jack","Mary","Tom","Lily","Jack","Rose"]
names_dict={ }
for key in names:
  if key  not in names_dict:
    names_dict[key]=1
  else:
    names_dict[key]+=1
print(names_dict)

【 试一试】 已知有三位学生参加了主题演讲的记录列表:
names=[“Tom”,“Jack”,“Mary”,“Tom”,“Lily”,“Jack”,“Rose”],请统计出每个学生参加活动的次数,并按降序输出,结果如下:
Tom 2
Jack 2
Lily 1
Mary 1
Rose 1

#E5-5.py
names=["Tom","Jack","Mary","Tom","Lily","Jack","Rose"]
names_dict={ }
for key in names:
  if key not in names_dict:
    names_dict[key]=1
  else:
    names_dict[key]+=1
names_list=list(names_dict.items())
names_list.sort(key=lambda x:x[1],reverse=True)
for i in range(len(names_list)):
  name,count=names_list[i]
  print("{0:<10}{1:<5}".format(name,count))

【 试一试】 编写购物车程序,购物车类型为列表类型,列表的每个元素为一个字典类型,字典键值包括"name",“price”,编写程序实现如下功能:
(1)创建购物车:键盘输入商品信息(用空格隔开),并输出商品列表。例如输入:
电脑 3999
电视机 2980
冰箱 3289
洗衣机 2199
购物车列表为:
shoppingCart=[{“name”:“电脑”,“price”:3999}, {“name”:“电视机”,“price”:2980},
{“name”:“冰箱”,“price”:3289}, {“name”:“洗衣机”,“price”:2199}]
(2)从键盘输入用户资产(如3000),若购物车中商品总额大于用户资产,输出提示"您的余额不足!",否则输出提示"购买成功!"

(1)创建购物车:键盘输入商品信息(用空格隔开),并输出商品列表

#购物车程序
#E5-6.py
shoppingCart=[]
while True:
  goodsDict={}
  s=input(“请输入商品名称价格(空格分隔):”
  if s==”exit”
break
  else:
ls=s.split()
goodsDict[“name”]=ls[0]
goodsDict[“price”]=int(ls[1])
shoppingCart.append(goodsDict)
print(shoppingCart)

(2)从键盘输入账户余额(如3000),若购物车中商品总额大于账户余额,输出提示"您的余额不足!",否则输出提示"购买成功!"

#购物车程序
#E5-6.py
shoppingCart=[]
while True:
  goodsDict={}
  s=input(“请输入商品名称价格(空格分隔):”
  if s==”exit”
break
  else:
ls=s.split()
goodsDict[“name”]=ls[0]
goodsDict[“price”]=int(ls[1])
shoppingCart.append(goodsDict)
print(shoppingCart)

ye=int(input(“请输入账户余额:”)
goodsSum=0
for i in range(len(shoppingCart)):
  goodsSum=goodsSum+shoppingCart[i][“price”]
if goodsSum>ye:
  print(“您的余额不足!”)
else:
  print(“购买成功!”)

【 试一试】 已知列表 aList=[14,89,23,65,78,39,98,41,11,87],将所有大于等于60的值保存至字典的关键字’>=60’对应的值(列表)中,将小于60的值保存至字典的关键字’<60’对应的值(列表)中,即{’>=60’:大于等于60的所有值列表,’<60’:小于60的所有值列表}。
程序的运行结果为:
{’<60’: [14, 23, 39, 41, 11], ‘>=60’: [89, 65, 78, 98, 87]}

#E5-7.py
aList=[14,89,23,65,78,39,98,41,11,87]
aDict={}
List1,List2=[],[]
for item in aList:
  if item >=60:
List1.append(item)
aDict[“>=60”]=List1
  else:
List2.append(item)
aDict[“<60”]=List2
print(aDict)

第六章 函数

6.1 函数的基本使用

6.2 函数的参数和返回值

6.3 变量作用域

6.4 lambda函数

6.5 time库

知识导入

【微实例】 为朋友唱生日歌,歌词为:
Happy birthday to you!
Happy birthday to you!
Happy birthday ,dear <名字>
Happy birthday to you!
编写程序为Mike和Lily输出生日歌。

#简单实现
print("Happy birthday to you!")
print("Happy birthday to you!")
print("Happy birthday,dear Mile !")
print("Happy birthday to you!")
如何将其功能封装起来,为不同的人输出生日歌呢?
  • 人们在求解某个复杂问题时,通常采用逐步分解、分而治之的方法,也就是将一个大问题分解成若干个比较容易求解的小问题,然后分别求解。
  • 程序员在设计一个复杂的应用程序时,当编写的代码越来越多,越来越复杂,为了使程序更简洁、可读性更好、易于维护,可把整个程序划分成若干个功能较单一的程序模块,再把所有的程序模块像搭积木一样组装起来。
  • Python语言通过函数来实现程序的模块化,模块可以看作是一组函数的集合,一个模块可以包含若干个函数。

6.1 函数的基本使用

函数

  • 函数是一段具有特定功能的、可重用的语句组
  • 函数也可以看作是一段具有名字的子程序,可以在需要的地方调用执行
  • 函数能够完成特定的功能,与黑盒类似,对函数的使用不需要了解函数内部实现原理,只要了解函数的输入输出方式即可
  • Python中函数包括内置函数(eval(),print()…),标准库中的函数(turtle.circle(),random.randint()…),用户自定义函数
  • 通过使用函数主要完成两个目的:增加代码可读性与增加代码复用性

使用函数的优点

  • 一次编写,多次引用
  • 增加程序的可读性
  • 降低了代码的维护难度

1 函数的定义

def <函数名>(<形式参数列表>): 
  <函数体> 
return <返回值>

函数的定义

  • 函数定义以 def 关键字开头,后接函数名和圆括号()
  • 函数名可以是任何有效的Python标识符
  • 函数的参数列表用逗号隔开,参数列表里的参数是“形式参数”,简称“形参”
  • 函数体是函数每次调用时执行的代码,由一行或多行语句组成
  • return语句表示函数调用到此结束,并且将返回值传递给调用语句。如果没有return语句,仅表示执行了一段代码,在函数体结束位置将返回函数的调用处,不返回任何值

2 函数的调用

<函数名>(<实际参数列表>)
  • 函数的定义 也叫函数"声明",定义后的函数不能直接运行,需要经过"调用"才能得到运行。也就是函数要先定义再调用
  • “实际参数列表”简称“实参”用于指定相应的参数值。如果需要传递多个参数值,则各参数值使用逗号","分隔。如果该函数没有参数,则直接调用即可。
  • 每次使用函数可以提供不同参数作为输入,以实现对不同数据的处理;函数执行后,可以反馈相应的处理结果

函数的使用总结

def 榨果汁(水果):
   榨汁机工作
return 果汁
s=榨果汁(橙子)
print(s)
def 榨果汁(*水果):
   榨汁机工作
return 果汁
s=榨果汁(橙子,苹果,葡萄)
print(s)

1. 函数定义
使用def关键字定义为函数,同时需要确定函数名称、参数的个数、参数名称、并使用参数名称作为形式参数(占位符)编写函数内部代码。
2. 函数调用
通过函数名调用函数,并对函数的各个参数赋予实际值(实参),实际值可以是实际数据,也可以是在调用函数前已经定义过的变量或表达式。
3.函数执行
函数被调用后,使用实际参数(赋予形式参数的实际值)参与函数内部代码的运行,如果在函数运行过程中有输出语句则进行输出。
4.函数返回
函数执行结束后,根据return关键字的指示决定是否返回结果,如果返回结果,则结果将被放置到函数被调用的位置,函数使用完毕,程序继续运行。

def add(a,b): 
  return a+b
c=add(3,5)
print(c)
x,y=4,6
m=add(x,y)
print(m)

6.2 函数的参数和返回值

1 函数的参数

实际参数:

  • 当函数被调用时参数表中提供的参数称为实际参数,简称实参。
  • Python 中的变量保存的是对象的引用,调用函数的过程就是将实参传递给形参的过程。
  • 函数调用时,实参可分为位置参数和赋值参数两种情况。
#位置参数
def rectangle(x,y): 
   s=x*y
   return s

#赋值参数
print("area1=",rectangle(3,5))
print("area2=",rectangle(x=3,y=5))
print("area3=",rectangle(y=5,x=3))

程序的运行结果
area1= 15
area2= 15
area3= 15

形式参数:

  • 函数的参数在定义时可以指定默认值,带有默认值的参数是可选参数,不带默认值的参数为必选参数,必选参数在前,可选参数在后
  • 当函数被调用时,如果没有传入对应的参数值,则使用函数定义时的默认值替代
def rectangle(x,y=6):
   s=x*y
   return s
print("area1=",rectangle(3))
print("area2=",rectangle(x=3)
print("area3=",rectangle(3,5))
print("area3=",rectangle(y=5,x=3))

程序的运行结果
area1= 18
area2= 18
area3= 15
area3= 15

可变参数

  • <形式参数列表>为定义的传统形式参数,代表一组参数
  • *args 为可变参数。
  • 函数被调用时传入的参数个数会优先匹配 <形式参数列表>中参数的个数
  • *args 以元组的形式保存多余的参数
  • 当函数被调用时,如果没有传入对应的参数值,则使用函数定义时的默认值替代
def <函数名>(<形式参数列表>,*args): 
  <函数体>
  return <返回值列表>
def concat(*args,sep="/"):
  return sep.join(args)
print(concat("www","lnu","edu","cn"))
print(concat("www","lnu","edu","cn",sep="."))

运行结果
www/lnu/edu/cn
www.lnu.edu.cn

def getSum(x1,x2,*x3):
  total=x1+x2
  for i in x3:
    total+=i
  return total
print(getSum(1,2))
print(getSum(1,2,3,4,5))

运行结果
3
15

2 函数的返回值

函数的返回值

  • 无返回值、单一返回值和多返回值。
  • 返回值可以是任何数据类型。
  • return <表达式>语句用于退出函数,将表达式值作为返回值传递给调用方。不带参数值的 return 语句返回 None, None表示没有实际意义的数据。
#单一返回值
def rectangle(x,y):
   s=x*y
   return s
print("area1=",rectangle(3,5))
area2=rectangle(8,9)
print("V=",area2*10)
#多返回值
def rectangle(x,y):
  s=x*y
  c=(x+y)*2
  return s,c
#当return语句返回多个值时,这些值形成了一个元组数据类型,如(s,c)
print("area1=",rectangle(3,5)[0])
print("c=",rectangle(3,5)[1])
#无返回值
def rectangle(x,y):
  s=x*y
  c=(x+y)*2
  print("area1=",s)
  print("c=",c)
rectangle(3,5)

6.3 变量的作用域

变量的作用域

  • 变量的作用域即变量起作用的范围,是 Python 程序设计中一个非常重要的问题。
  • 变量可以分为局部变量和全局变量
  • 局部变量指在函数内部定义的变量,仅在函数内部有效,当函数退出时变量将不再存在
  • 全局变量指在函数之外定义的变量,在程序执行全过程有效
  • 全局变量在函数内部使用时,需 提前使用保留字global声明
def rectangle(x,y):
   s=x*y
   c=(x+y)*2
   return s,c
#s和c 是局部变量
print("area1=",rectangle(3,5)[0])
print("c=",rectangle(3,5)[1])
print("s=",s)  #会报错,因s是函数的局部变量
h=10
def rectangle(x,y):
  global h
#h 是全局变量
  v=x*y*h
  return v
print("v=",rectangle(3,5))
print("h=",h)

6.4 lambda函数

lambda函数(匿名函数)

  • 格式: lambda <参数列表>:<lambda体>
  • lambda是关键字声明,<参数列表>与函数的参数列表是一样的,但不需要小括号括起来,冒号后面是<lambda体>,lambda表达式的主要代码编写于lambda体内,类似于函数体。lambda体的函数只能用于定义简单的,能够在一行内表示的函数。
f=lambda x,y:x+y
print(f(10,20))

运行结果
30

综合实例

【例6-1】 编写程序,为Mike和Tom输出生日歌

#E6-1.py
def happyA ():
  print("Happy Birthday to you!")
def happyB(name):
  happyA()
  happyA()
  print("Happy birthda,dear{}!".format(name))
  happyA()
happyB("Mike")
print()
happyB("Tom")

6.5 time库

time库

  • time库是Python提供的处理时间标准库
  • time库提供系统级精确计时器的计时功能,可以用来分析程序性能,也可让程序暂停运行时间
  • 使用time库需要用import保留字,最基本的使用方式如下:
>>> import time
>>> time.localtime(   )#当地时间,已自动转化为北京时间
time.struct_time(tm_year=2020, tm_mon=4, tm_mday=17, tm_hour=17, 
tm_min=59, tm_sec=13, tm_wday=4, tm_yday=108, tm_isdst=0)
>>> t=time.localtime()
>>> t.tm_mon
4
>>> t.tm_mday
17

综合实例

【例6-2】 编写程序,为Mike输出生日歌

#E6-2.py
import time
def happyA ():
  print("Happy Birthday to you!")
def happyB(name):
  happyA()
  happyA()
  print("Happy birthda,dear{}!".format(name))
  happyA()
t=time.localtime()
if t.tm_mon==4 and t.tm_mday==22:
  happyB("Mike")

time库——时间处理功能

  • time库的功能主要包括:时间处理、时间格式化和计时
  • 时间处理:time.time()、time.localtime()、time.gmtime()、time.ctime()
  • 使用time.time()获取当前时间戳
  • 所谓时间戳,即从格林威治时间1970年01月01日00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数
>>>time.time()
1587117085.4883282
  • 使用time. gmtime()获取当前时间戳对应的struct_ time对象
  • 元组struct_time是一类对象,在Python中定义了一个元组struct_time将所有这些变量组合在一起,包括:4位数年、月、日、小时、分钟、秒等
序号属性
0tm_year4位年份
1tm_mon
2tm_mday
3tm_hour小时
4tm_min分钟
5tm_sec
6tm_wday一周第几日
7tm_yday一年第几日
8tm_isdst是否是夏令时
>>>time.gmtime()
time.struct_time(tm_year=2020, tm_mon=4, tm_mday=17, 
tm_hour=9, tm_min=59, tm_sec=19, tm_wday=4, 
tm_yday=108, tm_isdst=0)
>>> time.gmtime(1516939876.623)
time.struct_time(tm_year=2018, tm_mon=1, tm_mday=26, 
tm_hour=4, tm_min=11, tm_sec=16, tm_wday=4, 
tm_yday=26, tm_isdst=0)
  • 使用time. localtime()获取当前时间戳对应的 本地时间的struct_ time对象
>>> import time
>>> time.localtime()
time.struct_time(tm_year=2020, tm_mon=4, tm_mday=22, tm_hour=11, tm_min=29, 
tm_sec=24, tm_wday=2, tm_yday=113, tm_isdst=0)
>>> time.gmtime()
time.struct_time(tm_year=2020, tm_mon=4, tm_mday=22, tm_hour=3, tm_min=29, 
tm_sec=28, tm_wday=2, tm_yday=113, tm_isdst=0)
  • 使用time.ctime()获取当前时间戳对应的本地时间(北京时间),并转换为易读字符串
>>>time.ctime( now)  #now可省略
'Fri Apr 17 18:02:12 2020'
>>> time.ctime(1500001234.32)
'Fri Jul 14 11:00:34 2017'

time库——时间格式化功能

  • 使用time.mktime()、time.strftime()、time.strptime()进行时间格式化
  • 使用time.mktime(t)将struct_time对象t转换为时间戳,注意t代表当地时间
>>>t=time.localtime()
>>>time.mktime(t)
1566987981.0
>>>time.ctime(time.mktime(t))
'Wed Aug 28 18:26:21 2019'
  • 使用time.strftime() 是时间格式化最有效的方法,可以通过多种通用格式输出时间。该方法利用一个格式字符串,对时间格式进行表示
>>>t=time.localtime()
>>> time.strftime("%Y-%m-%d %H:%M:%S",t)   #注意大小写
'2020-04-22 10:57:24'
>>> time.strftime("%H:%M:%S %Y-%m-%d",t)
'10:59:05 2020-04-22'
>>> time.strftime("%m-%d-%Y %H:%M:%S ",t)
'04-22-2020 10:59:31 '
>>> time.strftime("%b %d %Y %H:%M:%S ",t)
'Apr 22 2020 11:43:31 '
  • strptime()方法与strftime()方法正好相反,用于提取字符串中的时间来生成strut_time对象,可以很灵活地作为time模块的输入接口
>>>t='2020-04-17 18:10:01'
>>>time.strptime(t,"%Y - %m - %d %H:%M:%S")
time.struct_time(tm_year=2020, tm_mon=4, tm_mday=17, tm_hour=18, 
tm_min=10, tm_sec=1, tm_wday=4, tm_yday=108, tm_isdst=-1)

综合实例

time库——计时
【例6-3】 编写程序,实现进度条功能

#E6-3.py
import time
def ptime():
  t=time.localtime()
  return time.strftime("%Y-%m-%d %H:%M:%S",t)
print("程序开始时间:",ptime())
for i in range(10):
  print("■"*i, sep="", end="")
  time.sleep(0.2)
print("\n下载完成")
print("程序结束时间:",ptime())

【试一试】 读程序,分析程序的运行功能

#E6-4.py
import time
lst = ["\\", "|", "/", "—"]
for i in range(20):
  j = i % 4
  print(lst[j], end="")
  time.sleep(0.2)

课后作业

1.雨课堂平台发布的《第六章综合小练》
2.中国大学Mooc平台上的单元测试

第七章 文件-1

7.1 文件的相关概念

7.2 文件的使用

7.3 文件的读/写操作

7.4 文件和目录操作

7.5 CSV文件格式读/写操作

7.6 JSON文件的操作(自学)

7.7 pydoc文件操作(自学)

知识导入

  • 在前面的章节中我们使用的原始数据很多都是通过键盘输入的,并将输入的数据放入指定的变量中,若要处理(计算、修改、删除等)这些处据,可以从指定的变量中取出并进行处理。
  • 但是在数据量大,数据访问频繁以及数据处理结果需要反复查看或使用时,就有必要将程序的运行结果保存下来。
  • 为了解决以上问题,Python引入了文件,将这些待处理的数据存储在指定的文件中,当需要处理文件中的数据时,可以通过文件处理函数,取得文件内的数据并存放到指定的变量中进行处理,数据处理完毕后再将数据存回到指定的文件中。
  • 有了对文件的处理,不但数据容易维护,而且同一个程序可处理数据格式相同但文件名不同的文件,增加了程序的使用弹性。

7.1 文件的相关概念

文件

  • 文件是数据的集合和抽象,以文本、图像、音频、视频等形式存储在计算机的外部存储介质上
  • 根据文件的存储格式不同,可以分为:文本文件二进制文件

1 文本文件

文本文件

  • 文本文件是由字符组成,这些字符可以按ANSI、UTF-8或者Unicode等格式编码
  • 文本文件可看作是存储在磁盘上的长字符串,例如一个txt格式的文本文件
  • 文本文件的内容便于查看和编辑,存取时需要编解码,要花费一定的转换时间。
  • 大部分文本文件都可以通过文本编辑软件或文字处理软件创建、修改和读取,如常见的软件是记事本、UltraEdit等。

2 二进制文件

二进制文件

  • 二进制文件存储的是由0和1组成的二进制,没有统一的字符编码,只能当作字节流,而不能看作是字符串
  • 二进制文件内部数据的组织格式与文件用途有关
  • 例如png格式的图片文件,avi格式的视频文件

3 文本文件与二进制文件的区别

【微实例】 理解文本文件和二进制文件的区别
用文本编辑器生成一个包含“中国是个伟大的国家!”的txt格式文本文件,命名为7-1.txt
分别用文本文件和二进制文件方式读入 ,并打印输出效果

tFile=open("7-0.txt","rt")
print(tFile.readline())
tFile.close()
bFile=open("7-0.txt","rb")
print(bFile.readline())
bFile.close()

运行结果
中国是个伟大的国家!
b’\xd6\xd0\xb9\xfa\xca\xc7\xb8\xf6\xce\xb0\xb4\xf3\xb5\xc4\xb9\xfa\xbc\xd2\xa3\xa1’

【可以看到,采用文本方式读入文件,文件经过编码形成字符串,打印出有含义的字符;采用二进制方式打开文件,文件被解析为字节(Byte)流】

4 文件指针

文件指针

  • 文件指针是文件操作的重要概念, Python用文件指针表示当前读/写位置。在文件读/写过程中,文件指针的位置是自动移动的。
  • 只读方式打开文件时,文件指针指向文件开头,向文件中写数据追加数据时,指针指向文件末尾。通过设置文件指针的位置,可以实现文件的定位读写。
tFile=open("7-0.txt","rt")
print(tFile.readline())
tFile.close()
bFile=open("7-0.txt","rb")
print(bFile.readline())
bFile.close()

7.2 文件的打开与关闭

文件

  • Python对文本文件和二进制文件采用统一的操作步骤,即“打开-操作-关闭”
  • 首先将文件“打开”指,使得当前程序有权操作这个文件
  • 打开后的文件处于占用状态,此时,另一个进程不能操作这个文件。可以通过一组方法读取文件的内容或向文件写入内容。此时,文件作为一个数据对象存在,采用<a>.<b>()方式进行操作
  • 操作之后需 要将文件关闭,关闭将释放对文件的控制使文件恢复存储状态

open()函数

  • Python用内置的 open()函数打开文件,并创建一个文件对象。或者说返回一个操作这个文件的变量。
  • 格式:<文件对象>=open(<文件名>[,<打开方式>])
  • <文件名>可以是包含文件名的完整路径(如 “d:\abc\7-1.txt”)。如果只有文件名(“7-1.txt”),没有带路径的话,那么Python会在当前文件夹中去找到该文件并打开
  • <打开方式>用于控制使用何种方式打开文件
f=open("c:\\text\\score.txt","r")
f=open("c:/text/score.txt","r")
打开模式含义
“rt"或"r”只读打开文本文件,只允许读数据
“wt"或"w”只写打开或建立一个文本文件,只允许写数据
“at"或"a”追加打开一个文本文件,并在文件末尾写数据
“rb”只读打开一个二进制文件,并允许读数据
“wb”只写打开或建立一个二进制文件,只允许写数据
“ab”追加打开一个二进制文件,并在文件末尾写数据

注:‘r’,‘w’,‘a’可以和’b’,‘t’,’+'组合使用,形成既表达读写又表达文件模式的方式

打开模式含义
"rt+“或"r+”读写打开一个文本文件,允许读和写
"wt+“或"w+”读写打开或建立一个文本文件,允许读和写
"at+“或"a+”读写打开一个文本文件,允许读,或在文件末尾追加数据
“rb+”读写打开一个二进制文件,允许读和写
“wb+”读写打开或建立一个二进制文件,允许读和写
“ab+”读写打开一个二进制文件,允许读,或在文件末尾追加数据

打开文件常用组合

#以文本方式只读打开一个文件,读入后不能对文件进行修改
f=open("c:\\text\\score.txt","r")或 f=open("c:\\text\\score.txt","r")

#以文本方式可读写地打开一个文件,可以读入并修改文件
f=open("c:\\text\\score.txt","r+")

#以文本方式打开一个文件,准备覆盖写入一批内容,并保存为新文件
f=open("c:\\text\\score.txt","w")

#以文本方式打开一个空文件或已有文件,追加形式写入一批内容,更新原文件
f=open("c:\\text\\score.txt","a+")

#以二进制方式只读打开一个文件,读入后不能对文件进行修改
f=open("c:\\text\\score.txt","rb")

close()方法

  • 文件使用结束后要用close()方法关闭,以防止其被误操作而造成文件信息的破坏和文件信息的丢失
  • 格式:<文件对象>.close()
  • 通常情况下,Python 操作文件时,使用内存缓冲区缓存文件数据。关闭文件时,Python 将缓存的数据写入文件,然后关闭文件,释放对文件的引用
  • 关闭文件是断开文件对象与文件之间的关联,此后不能再继续通过该文件对象对该文件进行读写操作

【例7-1】 新建一个文本文件a.txt,其内容为"千里之行,始于足下",保存在"D:\python"。编写 程序,打开该文件,向其中追加内容“温故而知新”,然后读取该文件内容,并关闭该文件

#E7-1.py
f=open("d:\\python\\a.txt","a+")#打开文件,创建文建对象f,以追加写方式向其写入内容
f.write("\n温故而知新")   #向文件对象f追加写入"换行"及"温故而知新"
f.seek(0,0)   #将文件指针定位到文件对象f开头
print(f.readline())   #输出该文件对象f第一行内容
print(f.readline())   #输出该文件对象f第二行内容
f.close() 

7.3 文件读写

文件读

  • 当文件被打开后,根据文件的访问模式可以对文件进行读操作
  • 根据打开方式不同,读文件的方式也会不同
  • 如果文件是以文本文件方式打开的,默认情况下,程序按照当前操作系统的编码方式来读文件,也可以指定编码方式来读文件
  • 如果文件是以二进制文件方式打开的,则按字节流方式读
  • 文件对象提供了三种读取方法:read()、readline()和readlines()

文件读——read()

  • 格式:f.read([size])
  • f为文件对象,表示从文件中读入整个文件内容,也就是说读取到文件结束为止。如果有参数size,表示读入前size长度的字符串或字节流
  • 如果文件不大,可以一次性将文件内容读入,保存到程序内部变量中
  • f.read()返回的结果是一个字符串
>>> f=open("d:/python/a.txt","r") 
>>> s=f.read()
>>> print(s)
千里之行,始于足下
温故而知新
>>> f.close()
>>> f=open("d:/python/a.txt","r") 
>>> s=f.read(9)
>>> print(s)
千里之行,始于足下
>>> f.close()

文件读——readline()

  • 格式:f.readline([size])
  • f为文件对象,表示从文件中读取一 行内容。如果有参数size,表示读入该行前size长度的字符串或字节流
  • f.readline()返回的结果是一个字符串
  • 如果当前处于文件末尾,则返回空串
>>> f=open("d:/python/a.txt","r") 
>>> s=f.readline()
>>> print(s)
千里之行,始于足下
>>> s=f.readline()
>>> print(s)
温故而知新
>>> f.close()
>>> f=open("d:/python/a.txt","r") 
>>> s=f.readline(4)
>>> print(s)
千里之行
>>> s=f.readline(4)
>>> print(s)
,始于足
>>> f.close()

文件读——readlines()

  • 格式:f.readlines([hint])
  • 从文件中读入所有行,以每行为元素形成一个列表
  • 如果有参数hint,表示从当前读写位置开始需要以行为单位至少读出的字符数或字节数
  • 如果当前文件指针处于文件末尾,则返回空列表
>>> f=open("d:/python/a.txt","r") 
>>> ls=f.readlines()
>>> print(ls)
['千里之行,始于足下\n', '温故而知新']
>>> ls=f.readlines()
>>> print(ls)
[ ]
>>> f.close()
>>> f=open("d:/python/a.txt","r") 
>>> ls=f.readlines(4)
>>> print(ls)
['千里之行,始于足下\n']
>>> ls=f.readlines(4)
>>> print(ls)
['温故而知新\n']
>>> f.close()

文件读——遍历文件

  • 从文本文件中逐行读入内容并进行处理是一个基本的文件操作需求
  • 文本文件可以看作是由行组成的组合类型
  • 因此,可以使用循环遍历文件
f=open(<文件路径及名称>,"r")
for <变量名> in f:
  #处理一行数据
f.close()
f=open("d:/python/a.txt","r") 
for line in f:
  print(line)
f.close()

运行结果
千里之行,始于足下
温故而知新

文件写——write()

  • 格式:f.write(s)
  • 向文件写入一个字符串s或字节流s,并可返回写入的字符个数或字节流。每次写入后,将会记录一个写入指针
  • 该方法可以反复调用,在写入指针后分批写入内容,直至文件被关闭
  • 要显式地使用’\n’对写入文本进行分行,如果不进行分行,每次写入的字符串会被连接起来
f=open("d:/python/b.txt","w")
f.write("《凉州词》\n")
f.write("唐·王之涣\n")
f.write("黄河远上白云间,一片孤城万仞山。\n")
f.write("羌笛何须怨杨柳,春风不度玉门关。\n")
f.close()
>>>  f=open("d:/python/b.txt","w")
>>>  f.write("《凉州词》\n")
6
>>> f.close()

文件写——writelines()

  • 格式:f.writelines(<元素为字符串的列表>)
  • 在文件的当前位置将列表中的所有元素写入文件
  • 如需换行,则需在列表中添加换行符\n元 素
f=open("d:/python/c.txt","w")
ls=["《凉州词》\n","唐·王之涣\n","黄河远上白云间,一片孤城万仞山。\n",\
"羌笛何须怨杨柳,春风不度玉门关。\n"]
f.writelines(ls)
f.close()

【例7-2】 把一个包含两列内容的文件input.txt(如图所示),分割成两个文件col1.txt和col2.txt,每个文件有一列内容。

input.txt - -记事本
file1 file2
Python Java
C# VB
Go VC++

def split_file(filename):   #函数,把文件分成两列
  col1=[]
  col2=[]
  fd=open(filename)#以读模式打开文件input.txt,创建文件对象fd
  text=fd.read()   #读取文件对象全部内容返回一个字串符
  lines=text.splitlines()#以行为单位分割文本,返回列表lines
  for line in lines:  #遍历列表lines
    part=line.split()  #将每一行的元素进行分割
col1.append(part[0])
col2.append(part[1])
  return col1,col2

def write_list(filename,alist):  #把列表内容写入文件
  fd=open(filename,”w”)
  for line in alist:
fd.write(line+’\n’)

filename=’d:/python/input.txt’
col1,col2=split_file(filename)
write_list(‘d:/python/col1.txt’,col1)
write_list(‘d:/python/col2.txt’,col2)

col1=[ “File1”,“Python”,“C#”,“Go”]
col2=[“File2”,“Java”,“VB”,“VC++”]

lines:[‘file1\tfile2’, ‘Python\tJava’, ‘C#\tVB’, ‘Go\tVC++’]

特殊:

  • 前面介绍的读写方法都是读写字符串,对于其他类型数据则需要转换
  • 可使用Python标准库pickle库中的dump()load()方法实现二进制文件中其他类
    型数据对象的读写
  • pickle.dump(<数据>,<文件对象>)表示直接把其他类型的对象转换为字符串并存入文件中
  • pickle.load(<文件对象>)表示从二进制文件中读取字符串,并将字符串转换为Python的数据对象,该方法返回还原后的字符串
>>> import pickle
>>> x=100
>>> f=open ("d:/python/b.txt","wb+")
>>> pickle.dump(x,f)
>>> f.seek(0)
0
>>> x=pickle.load(f)
>>> x
100
>>> f.close()

文件的定位

  • Python在实际应用中,如果需要读取某个位置的数据,或向某个位置写入数据,需要定位文件的读/写位置,包括获取文件的当前位置,以及定位到文件的指定位置
  • 文件指针定位的方法有tell()seek()

文件的定位——tell ()

  • 格式:f.tell()
  • 返回文件的当前读写位置
>>> f=open("d:/python/col1.txt","r")
>>> f.tell()
0
>>> f.read(5)
'file1'
>>> f.read(4)
'\nPyt'
>>> f.tell()
10
>>> f.close()

文件的定位——seek()

  • 格式:f.seek(offset,whence)
  • 把文件指针移动到相对于whence的offset位置
  • whence指定移动的基准位置,默认值为0
    0:以文件开始位置作为基准点
    1:以当前位置为基准点
    2:以文件末尾为基准点
  • offset表示要移动的字节数,offset为正数表示向文件末尾方向移动,offset为负数表示向文件开头方向移动
>>> f=open("d:/python/col1.txt","rb")
>>> f.seek(0)
0
>>> f.read(2)
b'fi'
>>> f.seek(1,1)
3
>>> f.read(2)
b'e1'
>>> f.seek(2)
2
>>> f.read(1)
b'l'
>>> f.seek(0,2)
23

对于文本文件,f.seek(offset,whence),当whence参数为1或2时,offset参数必须为0

>>> f.close()
>>> f=open("d:/python/col1.txt","r")
>>> f.seek(0)
0
>>> f.read(2)
'fi'
>>> f.seek(1,1)
Traceback (most recent call last):
  File "<pyshell#19>", line 1, in 
<module>
f.seek(1,1)
io.UnsupportedOperation: can't do 
nonzero cur-relative seeks

第七章 文件-2

7.4 文件和目录操作

文件和目录操作包括:查看文件属性、复制和删除文件、创建和删除目录等
1.os 模块
2.os.path 模块
3.shutil 模块

1 os 模块

os模块(库):

  • Python内置的os模块提供了访问操作系统服务功能,如文件重命名,文件删除,目录创建,目录删除等
  • 使用时需先导入该模块import os
方法名含义
os.getcwd()显示当前的工作目录(路径)
os.chdir(newdir)改变当前工作目录,如os.chid
os.listdir(path)列出指定目录下所有的文件和目录
os.mkdir(path)创建单级目录
os.makedirs(path)创建多级目录
os.rmdir(path)删除单级目录
os.removedirs(path)删除多级目录
os.rename(old,new)将文件或目录old重命名为new
os.remove(path)删除文件

【课堂实践】准备:在D盘新建一个文件夹“python123”,在该文件夹下新建一个文本文件“a1.txt”,然后在IDLE下完成如下操作

>>> import os
>>> os.getcwd()#python安装目录不同,返回的结果可能不同
'D:\\Python35' 
>>> os.chdir("d:/python123")
>>> os.getcwd()
'd:\\python123'
>>> os.listdir("d:/python123")
['a1.txt']
>>> os.mkdir("d:/python123/abc")
>>> os.makedirs("d:/python123/a/b/c")
>>> os.removedirs("d:/python123/a/b/c")
>>> os.rename("a1.txt","b1.txt")
>>> os.remove("d:/python123/b1.txt")

2 os.path 模块

os.path模块(库):

  • Python内置的os.path模块主要用于针对路径的操作
  • 使用时需先导入该模块import os.path
方法名含义
os.path.split(path)分割路径与文件名,返回元组(<路径>,<文件名>)
os.path.splitext(path)分割文件名与扩展名,返回元组(<文件名>,<扩展名>)
os.path.abspath(path)获得文件的绝对路径
os.path.dirname(path)去掉文件名,只返回目录路径
os.path.getsize(file)获得指定文件的大小,返回值以字节为单位
os.path.basename(path)去掉目录路径,只返回路径中的文件名
os.path.exists(path)判断文件或目录是否存在

【课堂实践】准备:在D盘新建一个文件夹“python123”,在该文件夹下新建一个文本文件“a1.txt”,然后在IDLE下完成如下操作

import os.path
>>> os.path.split("d:/python123/a1.txt")
('d:/python123', 'a1.txt')
>>> os.path.splitext("d:/python123/a1.txt")
('d:/python123/a1', '.txt')
>>> os.chdir("d:/python123")
>>> os.path.abspath("a1.txt")
'd:\\python123\\a1.txt'
>>> os.path.dirname("d:/python123/a1.txt")
'd:/python123'
>>> os.path.basename("d:/python123/a1.txt")
'a1.txt'
>>> os.path.exists("d:/python123/a1.txt")
True

综合实例

【例7-3】把“d:\pyton123”路径下的所有.jpg图片文件名称加上“_Python”,如将“a1.jpg”修改文件名为“a1_Python.jpg”。(准备:在d:\python123目录下存储4张图片,图片的名字为*.jpg)

#E7-3.py
import os
imgDir="d:/python123"

for filename in os.listdir(imgDir):  #将该目录下所有文件返回一个列表,遍历该列表
  lists=filename.split('.')#将文件名分割成包含主文件名和扩展名的列表lists
  if lists[-1]=="jpg":#取扩展名,判断是否为jpg
    oldFile=imgDir+'/'+filename #原文件的绝对路径
    newFile=imgDir+'/'+lists[0]+'_Python'+'.'+fileExt  #重命名后文件的绝对路径
    os.rename(oldFile,newFile)  #重命名操作

7.5 CSV文件格式读/写操作

  • 数据包括文件存储和程序使用两个状态。
  • 存储不同维度的数据需要适合维度特点的文件存储格式,处理不同维度数据的程序需要使用相适应的数据类型或结构
  • 因此,对于数据处理,需要考虑存储格式以及表示和读写等两个问题

数据维度

  • 一组数据在被计算机处理前需要进行一定的组织,表明数据之间的基本关系和逻辑,进而形成数据的维度
  • 根据数据的关系不同,数据组织可以分为:一维数据二维数据高维数据

一维数据

  • 一维数据,由对等关系的有序或无序数据组成,采用线性方式组织,对应于数学中的数组和集合等概念
  • 例如:国际经济合作论坛20国集团(G20) 成员是对等关系,表示为一维数据,无论采用何种方式分隔和表示,一维数据都具有线性特点

中国,美国,日本,德国,法国,英国,意大利,加拿大,俄罗斯 ,欧盟,澳大利亚,南非, 阿根廷,巴西,印度尼西亚,墨西哥,沙特阿拉伯,土耳其,韩国

二维数据

  • 二维数据,也称表格数据,由关联关系数据组成,采用表格方式组织,对应于数学中的矩阵
  • 例如:国家统计局发布的近5年我国粮食产量是二维数据,摘录部分如表格如示
指标2019年2018年2017年2016年2015年
粮食产量(万吨)66384.0065789.2266160.7266043.5166060.27
夏收粮食产量(万吨)14160.0013881.0214174.4614050.1614074.94
秋粮产量(万吨)49597.0049049.1848999.1048890.7848778.09
谷物产量(万吨)61368.0061003.5861520.5461666.5361818.41
稻谷产量(万吨)20961.0021212.9021267.5921109.4221214.19
玉米产量(万吨)26077.0025717.3925907.0726361.3126499.22

高维数据

  • 高维数据,由键值对类型的数据构成,采用对象组织,可以多层嵌套,属于整合度更好的数据组织方式,能表达更加灵活和复杂的数据关系
  • 高维数据在Web系统中十分常用,作为当今Internet组织内容的主要方式,高维数据衍生出HTML、XML、JSON等具体数据组织的语法结构
  • 例如,描述中国古典四大名著的JSON格式的高维数据表示,

“四大名著”:[
{“书名”: “红楼梦”, “作者”: “曹雪芹”},
{“书名”: “三国演义”, “作者”: “罗贯中”},
{“书名”: “水浒传”, “作者”: “施耐庵”},
{“书名”: “西游记”, “作者”: “吴承恩”}
]

CSV格式

  • CSV是国际通用的一、二维数据存储格式,采用逗号分隔数值的存储格式,在商业上和科学上广泛应用,尤其应用在程序之间转移表格数据
  • CSV的应用有如下一些规则:
  1. 纯文本格式,通过单一编码表示字符
  2. 以行为单位,开头不留空行,行之间没有空行
  3. 每行表示一个一维数据,多行表示二维数据
  4. 以逗号(英文、半角)分隔每列数据,列数据为空也要保留逗号
  5. 对于表格数据,可以包含或不包含列名,包含时列名放置在文件第一行

数据摘录于2020年3月国家统计局发布的能源产品产量

nycpcl.csv - 记事本
指标,本月,当月增速(%),累计增速(%)
原煤(万吨),33726.00,9.60,-0.50
天然气(亿立方米),168.60,11.20,9.10
原油(万吨),1656.30,-0.10,2.40
汽油(万吨),943.00,-21.00,-16.30
发电量(亿千瓦时),5525.10,-4.60,-6.80

CSV格式

  • CSV格式的每一行是一维数据,可以使用Python中的列表类型表示,整个CSV文件是一个二维数据,由表示每一行的列表类型作为元素,组成一个二维列表

【例7-4】 导入CSV格式数据到列表

#E7-4.py
fo=open("d:/python/nycpcl.csv","r")
ls=[]
for line in fo:
  ls.append(line.split(","))
print(ls)
fo.close()

程序运行结果
[[‘指标’, ‘本月’, ‘当月增速(%)’, ‘累计增速(%)\n’], [‘原煤(万吨)’, ‘33726.00’, ‘9.60’, ‘-0.50\n’], [‘天然气(亿立方米)’, ‘168.60’, ‘11.20’, ‘9.10\n’], [‘原油(万吨)’, ‘1656.30’, ‘-0.10’, ‘2.40\n’], [‘汽油(万吨)’, ‘943.00’, ‘-21.00’, ‘-16.30\n’], [‘发电量(亿千瓦时)’, ‘5525.10’, ‘-4.60’, ‘-6.80\n’]]

【例7-4】 导入CSV格式数据到列表
一次读入全部数据写入

#E7-4.py
fo=open("d:/python/nycpcl.csv","r")
ls=[]
for line in fo:
  #line=line.replace("\n","")
  line=line.strip("\n")
  ls.append(line.split(","))
print(ls)
fo.close()

程序运行结果
[[‘指标’, ‘本月’, ‘当月增速(%)’, ‘累计增速(%)’], [‘原煤(万吨)’, ‘33726.00’, ‘9.60’, ‘-0.50’], [‘天然气(亿立方米)’, ‘168.60’, ‘11.20’, ‘9.10’], [‘原油(万吨)’, ‘1656.30’, ‘-0.10’, ‘2.40’], [‘汽油(万吨)’, ‘943.00’, ‘-21.00’, ‘-16.30’], [‘发电量(亿千瓦时)’, ‘5525.10’, ‘-4.60’, ‘-6.80’]]

【例7-5】 逐行处理CSV格式数据

#E7-5.py
fo=open("d:/python/nycpcl.csv","r")
for line in fo:
  #line=line.replace("\n","")
  line=line.strip("\n") 
  ls=line.split(",")
  lns=""
  for s in ls:
    lns+="{:<15}".format(s)
  print(lns)
fo.close()

程序运行结果

指标 本月 当月增速(%) 累计增速(%)
原煤(万吨) 33726.00 9.60 -0.50
天然气(亿立方米) 168.60 11.20 9.10
原油(万吨) 1656.30 -0.10 2.40
汽油(万吨) 943.00 -21.00 -16.30
发电量(亿千瓦时) 5525.10 -4.60 -6.80

【例7-6】 一维数据写入CSV格式文件

#E7-6.py
fo=open("d:/python/nycpcl.csv","a+")
ls=["煤气(亿立方米)","1217.30","1.60","4.00"]
fo.write(",".join(ls)+"\n")
fo.close()

程序运行结果

nycpcl.csv - 记事本
指标,本月,当月增速(%),累计增速(%)
原煤(万吨),33726.00,9.60,-0.50
天然气(亿立方米),168.60,11.20,9.10
原油(万吨),1656.30,-0.10,2.40
汽油(万吨),943.00,-21.00,-16.30
发电量(亿千瓦时),5525.10,-4.60,-6.80
煤气(亿立方米),1217.30,1.60,4.00

【例7-7】 二维数据写入CSV格式文件操作,将nycpcl.csv文件的前三行读出来写入到a1.csv文件中

#E7-7.py
fo=open("d:/python/nycpcl.csv","r")
fw=open("d:/python/a1.csv","w")
ls=[]
i=0
for line in fo:
  ls.append(line.split(","))
  i+=1
  if i==3:
    break
for row in ls:
  fw.write(",".join(row))
fo.close()
fw.close()

程序运行结果

al.csv - 记事本
指标,本月,当月增速(%),累计增速(%)
原煤(万吨),33726.00,9.60,-0.50
天然气(亿立方米),168.60,11.20,9.10

第八章 Python第三方库安装及常用库介绍

8.1 Python第三方库简介

8.2 Python第三方库安装

8.3 jieba库的使用

8.4 wordcloud库的使用

8.1 Python第三方库简介

  • 近20年的开源运动产生了深植于各信息技术领域的大量可重用资源,形成了“计算生态”。
  • 编程领域形成的庞大“计算生态”,需要一种编程语言或方式将不同语言、不同特点、不同使用方式的代码统一起来。
  • 在计算生态思想指导下,编写程序的起点不再是探究每个具体算法的逻辑功能和设计,而是尽可能利用第三方库进行代码复用,探究运用库的系统方法。这种像搭积木一样的编程方式,称 为“模块编程”
  • Python从诞生之初致力于开源开放,建立 了全球最大的编程计算生态,至今已建立了9万多第三方库
  • Python官方网站(https://pypi.python.org/pypi)提供了第三方库索引功能, 这些库覆盖信息领域所有技术方向

8.2 Python第三方库安装

Python第三方库安装:

  • Python语言有标准库和第三方库两种库,标准库随Python安装包一起
    发布,用户安装Python后即可使用,而第三方库需要安装后才可使用
  • Python第三方库按照安装方式灵活性和难易度主要有以下安装方法:
    (1)pip工具安装
    (2)自定义安装【略】
    (3)文件安装
    其中最常用和最高效的安装方式:采用pip工具安装

pip工具安装:

  • pip是Python官方提供并维护的在线第三方库安装工具
  • pip是Python内置命令,需要通过命令行执行,执行pip –h命令将列出pip常用的子命令,注意,需要在“命令提示符”窗口运行pip命令,而不要在IDLE环境下运行pip命令
  • pip支持安装(install)、下载(download)、卸载(uninstall)、列表(list)、查看(show)、查找(search)等一系列安装和维护子命令
  • 安装一个库的命令格式如下(在“命令提示符”窗口输入pip命令):
    pip install <拟安装库名>
    例如 :pip install wordcloud
    pip工具将默认从网络上下载wordcloud 库安装文件并自动安装到系统中

文件安装:

  • 如果在windows平台下有些第三方库用pip工具无法安装,可以尝试使用文件安装
  • 美国加州大学尔湾分校提供了一个页面,帮助Python用户获得Windows可直接安装的第三方库文件,链接地址如下:
    http://www.lfd.uci.edu/~gohlke/pythonlibs
    选择适用于Python(如Python 3.7)解释器和64(32)位操作系统的对应.whl文件,下载后用pip命令进行安装

**安装补充:**如 anaconda的集成开发环境安装

8.3 jieba库

1 jieba库简介

2 jieba库分词函数

1 jieba库简介

jieba库:

  • 在自然语言处理技术中,中文分词是其他中文信息处理的基础,比如搜索引擎、机器翻译(MT)、语音合成、自动分类、自动摘要、自动校对等等,都需要用到分词
  • jieba 是Python中一个重要的第三方中文分词库,具有分词、添加用户词典、提取关键词和词性标注等功能
  • jieba库的安装( 在“命令提示符”窗口输入命令):
    pip install jieba
  • jieba 库的分词原理是利用一个中文词库,将待分词的内容与分词词库进行比对,通过图结构和动态规划方法找到最大概率的词组。它支持3 种分词模式:
    (1)精确模式:试图将句子最精确地切开,适合文本分析。
    (2)全模式:把句子中所有可以成词的词语都扫描出来,速度快,但是不能解决歧义问题。
    (3)搜索引擎模式:在精确模式的基础上,对长词再次切分,提高召回率,适用于搜索引擎分词

2 jieba库分词函数

jieba库:

  • jieba 库主要提供分词功能,可以辅助自定义分词词典。jieba 库中包含的主要函数如表格所示
函数说明
jieba.cut(s)精确模式,返回一个可迭代的数据类型,可以通过for循环来取里面的每一个词
jieba.cut(s,cut_all=True)全模式,输出文本s中所有可能的单词
jieba.cut_for_search(s)搜索引擎模式,适合搜索引擎建立索引的分词结果
jieba.lcut(s)精确模式,返回一个列表类型
jieba.lcut(s,cut_all=True)全模式,返回一个列表类型
jieba.lcut_for_search(s)搜索引擎模式,返回一个列表类型

【 例8-1】 jieba库的分词基本应用

>>>import jieba
>>>str1="AlphaGo是第一个战胜围棋世界冠军的人工智能机器人"
>>>jieba.lcut(str1)
['AlphaGo','是','第一个','战胜','围棋','世界冠军','的','人工智能','机器人']
>>>jieba.lcut(str1,cut_all=True)
['AlphaGo','是','第一','第一个','一个','战胜','围棋','世界','世界冠军','冠军','的','人工','人工智能','智能','智能机','机器','机器人']
>>>jieba.lcut_for_search(str1)
['AlphaGo','是','第一','一个','第一个','战胜','围棋','世界','冠军','世界冠军','的','人工','智能','人工智能','机器','机器人']
>>>jieba.cut(str1)
<generator object Tokenizer.cut at 0x000002326E6B03B8>
>>>[word for word in jieba.cut(str1)]
['AlphaGo','是','第一个','战胜','围棋','世界冠军','的','人工智能','机器人']

3 向jieba调整词典和自定义词典

调整字典

函数说明
jieba.add_word(word,freq=None,tag=None)向词典添加新闻
jieba.del_word(word)删除词典中的词
jieba.suggest_freq(segment,tune=True)可调节单个词语的词频,使其能(或不能)被拆分

【例8-2】jieba库的添加分词与调节词频

>>>import jieba
>>>str="甄善美爱Python"
>>>jieba.lcut(str2)
['甄善','美爱','Python']
>>>jieba.add_word("甄善美")
>>>jieba.lcut(str2)
['甄善美','爱','Python']
>>>st3="在运动中将有补给"
>>>jieba.lcut(str3)
['在','运动','中将','有','补给']
>>>jieba.suggest_freq(('中','将'),True)
494
>>>jieba.lcut(str3)
['在','运动','中','将','有','补给']

自定义词典:

  • 用户自定义的词典文件格式是每个词占一行,每一行分 3 部分:词语、词频(可省略)、词性(可省略),各部分用空格隔开,顺序不可颠倒
  • 通常的字典文件编码格式为 UTF-8。例如创建字典文件 dict1.txt结构如图所示:

dict.txt - 记事本
杨树芳 10
三级 1500
跳高 1500
当壁镇 5
创业处 7

  • jieba中添加自定义字典的语法格式如下,其中 <文件名> 为文件类对象或自定义词典文件的路径。
    jieba.load_userdict(<文件名>)

【例8-3】用户自定义字典的应用

>>>str4="杨树芳是当壁镇马拉松冠军也是国家三级跳高运动员"
>>>jieba.lcut(str4)
['杨树','芳是','当壁','镇','马拉松','冠军','也','是','国家','三级跳','高','运动员']
>>>jieba.load_userdict('C:\\Python36\\Lib\\site-packages\\jieba\\dict1.txt')
>>>jieba.lcut(str4)
['杨树芳','是','当壁镇','马拉松','冠军','也','是','国家','三级','跳高','运动员']

8.4 wordcloud库

wordcloud库

  • wordcloud是专门用于根据文本生成词云的Python第三方库
  • 词云又叫文字云,以词语为基本单元,对文本数据中出现频率较高的“关键词”在视觉上的突出呈现,形成“关键词云层”或“关键词渲染”类似云一样的彩色图片,从而一眼就可以领略文本数据的主要表达意思,以达到数据展示的多样性的目的

【例8-4】 每年的4月23日是世界读书日,其设立目的是为了推动更多的人去阅读和写作。中国古代有许多关于书的成语和鼓励人们多读书的诗句,请将“腹有诗书气自华”、“读书破万卷,下笔如有神”、“书到用时方恨少”这三句诗翻译成英文,编写程序将其生成词云图

from wordcloud import WordCloud
text="One who is filled with knowledge always behaves with elegance;\
Having pored over ten thousand volumes, one can write with godly power;\
It is when you are using what you have learned from books that you wish you had read more books than you have."
wcloud=WordCloud().generate(text)
wcloud.to_file("d:/python/a1.png")

wordcloud库

  • wordcloud库的核心是WordCloud类,所有的功能都封装在WordCloud类中
  • 使用时需要实例化一个WordCloud类的对象,并调用其generate(<文本>)方法将text文本转化为词云
  • wordcloud类在创建时有一系列可选参数,用于配置词云图片
  • wordcloud对象创建时的常用参数及常用方法如表格所示

WordCloud对象创建的常用参数

参数功能
front_path指定字体文件的完整路径,默认None
width生成图片宽度,默认400像素
height生成图片高度,默认200像素
mask词云形状,默认None,即方形图
min_font_size词云中最小的字体字号,默认4号
font_step字号步进间隔,默认1
max_font_size词云中最大的字体字号,默认None,根据高度自动调节
max_words词云图中最大词数,默认200
stopwords被排除词列表,排除词不在词云中显示
background_color图片背景颜色,默认黑色

WordCloud类的常用方法

方法功能
WordCloud.generate(<文本>)由文本生成词云
WordCloud.to_file(<文件名>)将词云图保存为文件名

【扩展 例8-4】

from wordcloud import WordCloud
text="One who is filled with knowledge always behaves with elegance;\
Having pored over ten thousand volumes, one can write with godly power;\
It is when you are using what you have learned from books that you wish you had read more books than you have."
wcloud=WordCloud(height=400,background_color="yellow").generate(text)
wcloud.to_file("d:/python/a2.png")

【例8-5】 修改【例8-4】,生成带有形状的词云
提示:
(1)需要提前准备好一张带形状的图片(*.png、*.jpg、*.jpeg等)
(2)需要用到scipy库将图像转换成ndarray类型,在安装wordcloud库时,scipy库会被作为依赖库自动安装。除此之外,也可以用numpy库和PIL处理图像,需要单独安装
(3)设置WordCloud( )对象中mask限制生成词云的形状

from wordcloud import WordCloud
from scipy.misc import imread  #或者from imgeio import imread
background_image=imread("d:/python/photo4.jpeg")
text="One who is filled with knowledge always behaves with elegance;\
Having pored over ten thousand volumes, one can write with godly power;\
It is when you are using what you have learned from books that you wish you had read more books than you have."
wcloud=WordCloud(mask=background_image,background_color='white').generate(text)
wcloud.to_file("d:/python/a3.png")

【例8-6】根据党的十九大报告全文,生成词云
提示:
(1) 准备文档“党的十九大报告全文.txt”
(2) 对于中文文本,分词外理需要由用户来完成,因此安装第三方库jieba库并使用。一般步骤是先将文本分词处理,然后以空格拼接,再调用wordcloud库函数
(3) 处理中文时还需要指定中文字体

from wordcloud import WordCloud
import jieba
f=open("d:/python/党的十九大报告全文.txt","r")
txt=f.read()
f.close( )
words=jieba.lcut(txt)
newtxt=''.join(words) #用空格连接列表元素为字符串font="c:/Windows/Fonts/simhei.ttf"
wcloud=WordCloud(font_path=font).generate(newtxt)
wcloud.to_file("d:/python/a4.png")

【扩展 例8-6】 根据党的十九大报告全文,生成带形状的词云

from wordcloud import WordCloud
import jieba
from scipy.misc import imread
f=open("d:/python/党的十九大报告全文.txt","r")
txt=f.read()
f.close()
words=jieba.lcut(txt)
newtxt=''.join(words)
font="c:/Windows/Fonts/simhei.ttf"
background_image=imread("d:/python/photo13.jpg")
wcloud=WordCloud(font_path=font,mask=background_image,background_color\
=“white").generate(newtxt)
wcloud.to_file(“d:/python/a5.png")

【温馨提示】 程序运行若出现如下提示
ImportError: cannot import name ‘imread’ from ‘scipy.misc’……….
原因是在最新版本的scipy库中已移除imread函数
可参考:方法1或方法2尝试解决
方法1需要在命令提示符窗口安装第三方库 imageio
pip install imageio
方法2需要在命令提示符窗口安装第三方库 numpy和PIL(实际安装pillow)
pip install numpy
pip install pillow

方法一

from wordcloud import WordCloud
import jieba
from scipy.misc import imread #from imageio import imread
f=open("d:/python/党的十九大报告全文.txt","r")
txt=f.read()
f.close()
words=jieba.lcut(txt)
newtxt=''.join(words)
font="c:/Windows/Fonts/simhei.ttf"
background_image=imread("d:/python/photo13.jpg")
wcloud=WordCloud(font_path=font,mask=background_image,background_color\
="white").generate(newtxt)
wcloud.to_file("d:/python/a5.png")

方法二

from wordcloud import WordCloud
import jieba
from scipy.misc import imread '''import PIL.Image as image 
                                 import numpy as np'''

f=open("d:/python/党的十九大报告全文.txt","r")
txt=f.read()
f.close()
words=jieba.lcut(txt)
newtxt=''.join(words)
font="c:/Windows/Fonts/simhei.ttf"
background_image=imread("d:/python/photo13.jpg") #np.array(image.open("d:/python/photo13.jpg"))
wcloud=WordCloud(font_path=font,mask=background_image,background_color\
="white").generate(newtxt)
wcloud.to_file("d:/python/a5.png")

【课后思考】 根据“红楼梦.txt”,生成带有形状的词云

from wordcloud import WordCloud
import jieba
from scipy.misc import imread
f=open("d:/python/红楼梦.txt","r",encoding="utf-8")  #"utf-8"表示文件编码
font="c:/Windows/Fonts/simhei.ttf"
background_image=imread("d:/python/photo11.jpg")
txt=f.read()
f.close()
words=jieba.lcut(txt)
newtxt=''.join(words)
wcloud=WordCloud(font_path=font,mask=background_image,background_color="white").generate(newtxt)
wcloud.to_file("d:/python/a6.png")

综合大作业

【综合大作业】每名学生上交 1 份电子版作业,要求自行设计一个主题,并利用 wordcloud 生成基于中文文本的带有形状的词云。将本次作业创建一个名为“学号班级姓名”的压缩包,通过雨课堂试卷进行提交。压缩包内具体包括如下内容:

  • 编写的程序文件,文件名为“学号班级姓名.py”
  • 生成的词云图片,文件名为“学号班级姓名.png”
  • 原始文本,文件名为“学号班级姓名 yswb.txt”
  • 原始图像,文件名为“学号班级姓名 ystx.jpg” 实验报告,文件名为“学号班级姓名实验报告.docx”
    提示:
    (1)文件名“学号班级姓名”(如190101123中文1张小小),在其中间不要加空格或其他符号
    (2)实验报告模版请从QQ群文件中下载

补充:常用第三方库

库名功能
openpyxl读写Excel文件
python-docx读写Word文件
numpy、pandas、scipy数据分析
matplotlib数据可视化或科学计算可视化
scrapy、requests爬虫框架
pygame、Panda3D游戏开发
sklearn机器学习
tensorflow深度学习
Django、FlaskWeb开发

【总结】第三方库安装

(1)pip install <库名>[==version]在线安装指定库(的指定版本)

例如:pip install jieba

pip install jieba -i https://pypi.tuna.tsinghua.edu.cn/simple/

(2)pip install <库名>.whl 离线安装第三方库(需先下载)

例如:Python官方网站(https://pypi.python.org/pyi)下载第三方库wordcloud

pip install wordcloud-1.7.0-cp37-co37m-win_amd64.whl

【总结】第三方库导入

>>>import jieba
>>>jieba.lcut("中国是一个伟大的国家")
['中国','是','一个','伟大','的','国家']

>>>from jieba import lcut
>>>lcut("中国是一个伟大的国家")
['中国','是','一个','伟大','的','国家']

>>>import jieba as j
>>>j.lcut("中国是一个伟大的国家")
['中国','是','一个','伟大','的','国家']

>>>from jieba import lcut as exactCut
>>>exactCut("中国是一个伟大的国家")
['中国','是','一个','伟大','的','国家']
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值