Python 程序设计语言 笔记(六)
来源:互联网 发布:金庸和古龙 知乎 编辑:程序博客网 时间:2024/06/12 01:02
第五周 文件与字典
5.1 文件的基础
(1)Python中的字符串类型未编码— 使用encode()编码,decode()解码
(2)多行文本:【注意】如果在shell中直接输入带有换行符\n的字符串,则保持原样输出
(3)二进制文件:照片、音乐、视频、计算机程序等
优点:① 更加节省空间;② 采用二进制无格式存储;③ 更精确;④ 编码是变长的,灵活利用率高
不同的二进制文件,解码方式不同
5.2 文件的基本处理
(1)打开文件 —open() 建立磁盘上的文件与程序中的对象相关联,通过相关的文件对象获得
<variable>= open(<name>, <mode>)
磁盘文件名 打开模式
字符表示
打开模式描述
r
只读。如果文件不存在,则输出错误
w
只写(如果文件不存在,则自动创建文件)
a
附加到文件末尾
rb
只读二进制文件,如果文件不存在,则输出错误
wb
只写二进制文件,如果文件不存在,则自动创建文件
ab
附加到二进制文件末尾
r+
读写
例:打开“numbers.dat”文本文件:
>>> infile = open(“numbers.dat”,“r”)
打开“music.mp3”的音频文件(二进制文件):
>>> infle = open(“music.mp3”,”rb”)
(2)文件操作:读取、写入、定位、追加、计算
① 文件读取:
操作名称
操作含义
read()
返回值为包含整个文件内容的一个字符串
readline()
返回值为文件下一行内容的字符串
readlines()
返回值为整个文件内容的列表
每项是以换行为结尾的一行字符串
例:程序5.2.1
def main():fname = input(“Enter filename:”)infile = open(fname.“r”)data = infile.read()print(data)for i in range(5):line = infile.readline()print(line[:-1])main()
② 文件写入:
操作名称
操作含义
write()
把含有本文数据或二进制数据块的字符串写入文件中
writelines()
针对列表操作,接受一个字符串列表作为参数
将它们写入文件,并且行结束符不会被自动加入
例:
>>>> outfile = open(“outfile.txt”,”w”)
>>>> outfile.writelines([“Hello”, ” ”, ”world”])
>>>> outfile.close()
>>>> infile = open(“outfile.txt”, “r”)
>>>> infile.read()
‘Helloworld’
③ 文件遍历:如: 拷贝文件,根据数据文件定义行走路径,将文件由一种编码转换为另外一种编码
通用代码框架:
file = open(someFile, ”r”)for line in file.readlines(): # 可简化为 for line in file:#处理一行文件内容file.close()
例:文件拷贝
程序5.2.2
def main():# 用户输入文件名 f1 = input("Enter a soucefile:").strip() f2 = input("Enter a soucefile:").strip() # 打开文件 infile = open(f1,"r") outfile = open(f2,"w") # 拷贝数据 countLines = countChars = 0 for line in infile: countLines += 1 countChars += len(line) outfile.write(line) print(countLines,"linesand",countChars,"chars copied") infile.close() outfile.close()main()
【运行结果】
Enter a soucefile:s.txt
Enter a soucefile:q.txt
1 lines and 15chars copied
(3)关闭文件 — close() 切断文件与程序的联系
写入磁盘,并释放文件缓冲区
5.3 文件实例
【实例一】根据文件date.txt中的数据,使用turtle库来动态绘制图形路径
元素1:路径前进像素数
元素2:转动方向,0为左,1为右
元素3:转动角度
元素4-6:绘制颜色的RGB值
例:第一行 — 绘制路径前进300个像素,向左转动144度,路径线段颜色为红色
【IPO】
输入:数据文件
处理:读取数据文件,并根据数据内容和要求绘制路径
输出:构建窗口,并输出图形
【程序实现】
程序5.3.1# 根据数据文件在窗口中动态路径绘制import turtledef main(): # 设置窗口信息 turtle.title('数据驱动的动态路径绘制') turtle.setup(800,800,0,0) # 设置画笔 pen =turtle.Turtle() pen.color("red") pen.width(5) pen.shape("turtle") pen.speed(5) # 读取文件 result = [] file = open("data.txt","r") for line in file: result.append(list(map(float, line.split(',')))) print(result) for i inrange(len(result)): pen.color(result[i][3],result[i][4],result[i][5]) pen.fd(result[i][0]) if result[i][1]: pen.rt(result[i][2]) else: pen.lt(result[i][2]) pen.goto(0,0)if __name__ == '__main__':main()
【运行结果】
【文件实例二】多文件读写 — 合并邮箱簿和电话簿文件
【IPO】输入:电话簿、邮箱地址簿文件
处理:将两个文件内容进行合并
输出:合并后的包含电话和邮箱地址的文件
【程序实现】
程序5.3.2def main(): ftele1 = open('TeleAddressBook.txt', 'rb') ftele2 = open('EmailAddressBook.txt', 'rb') ftele1.readline() # 跳过第一行 ftele2.readline() lines1 = ftele1.readlines() lines2 = ftele2.readlines() list1_name = [] list1_tele = [] list2_name = [] list2_email = [] for line in lines1: # 获取第一个文本中的姓名和电话信息 elements = line.split() list1_name.append(str(elements[0].decode('gbk'))) list1_tele.append(str(elements[1].decode('gbk'))) # 将文本读出来的bytes转换为str类型 for line in lines2: # 获取第二个文本中的姓名和邮件信息 elements = line.split() list2_name.append(str(elements[0].decode('gbk'))) list2_email.append(str(elements[1].decode('gbk'))) # 开始处理 # lines = [] lines.append('姓名\t 电话 \t 邮箱\n') # 按索引方式遍历姓名列表1 for i in range(len(list1_name)): s = '' if list1_name[i] in list2_name: j = list2_name.index(list1_name[i]) # 找到姓名列表1对应列表2中姓名 s = '\t'.join([list1_name[i],list1_tele[i], list2_email[j]]) s += '\n' else: s = '\t'.join([list1_name[i],list1_tele[i], str(' ----- ')]) s += '\n' lines.append(s) # 处理姓名列表2中剩余的姓名 for i in range(len(list2_name)): s = '' if list2_name[i] not in list1_name: s = '\t'.join([list2_name[i],str(' ----- '), list2_email[i]]) s += '\n' lines.append(s) ftele3 = open('AddressBook.txt', 'w') ftele3.writelines(lines) ftele3.close() ftele1.close() ftele2.close() print("The addressBooks aremerged!")if __name__ =="__main__":main()
5.4 字典 — 针对非序列集合而提供的一种数据类型,<键> → <值>
(1)概念:通过任意键值查找集合中值信息的过程叫映射,python中通过字典实现映射
该集合以键位索引,同一个键信息对应一个值
(2)与序列类型的区别: ① 存取和访问的方式
② 键的类型
③ 排列方式
④ 映射值的方式
5.5 字典的操作:
(1)为字典增加一项,格式:
dictionaryName[key] = value
(2)访问字典中的值,格式:
dictionaryName[key]
若访问的值不存在,则返回错误信息
(3)删除字典中的一项,格式:
del dictionaryName[key]
(4)字典的遍历,格式:
for key in dictionaryName:
print(key +“ :” +str(dictionaryName[key]))
可遍历的内容:① 键 ② 值 ③ 项 ④ 键值对
for keys/values/itemsin dictionaryName.keys/values/items():
print(key/value/item)
for item, value in adict.items():
print(item,value)
(5)一个键是否在字典中:in或者not in
(6)字典不提供拼接和重复操作方法,其余操作符都可正常使用,字典是无序的
(7)字典方法:
方法名称
方法含义
keys():tuple
返回一个包含字典所有key的列表
values():tuple
返回一个包含字典所有value的列表
items():tuple
返回一个包含所有键值的列表
clear():None
删除字典中的所有项目
get(key):value
返回字典中key对应的值
pop(key):val
删除并返回字典中key对应的值
update(tuple)
将字典中的键值添加到字典中
5.6 字典实例
【实例一】“统计词频”问题:
【问题描述】统计文章重复词语,有助于搜索引擎对网络信息的检索与归档
【IPO】 输入:从文件中读取一篇英文文章
处理:统计文件中每个单词的出现频率
输出:将最常出现的10个单词及出现次数,以下图表形式输出
【分析】①建立用于词频计算的空字典,对文本的每一行计算词频
② 从字典中获取数据对到列表中,对列表中的数据交换位置并排序
③ 用turtle库绘制统计词频结果图表
【程序实现】
程序5.6.1
import turtle
##全局变量##
#词频排列显示个数
count = 10
#单词频率数组-作为y轴数据
data = []
#单词数组-作为x轴数据
words = []
#y轴显示放大倍数-可以根据词频数量进行调节
yScale = 6
#x轴显示放大倍数-可以根据count数量进行调节
xScale = 30
################# Turtle Start ####################
#从点(x1,y1)到(x2,y2)绘制线段
def drawLine(t, x1, y1, x2, y2):
t.penup()
t.goto (x1, y1)
t.pendown()
t.goto (x2, y2)
# 在坐标(x,y)处写文字
def drawText(t, x, y, text):
t.penup()
t.goto (x, y)
t.pendown()
t.write(text)
def drawGraph(t):
#绘制x/y轴线
drawLine (t, 0, 0, 360, 0)
drawLine (t, 0, 300, 0, 0)
#x轴:坐标及描述
for x in range(count):
x=x+1 #向右移一位,为了不画在原点上
drawText(t, x*xScale-4, -20,(words[x-1]))
drawText(t, x*xScale-4,data[x-1]*yScale+10, data[x-1])
drawBar(t)
#绘制一个柱体
def drawRectangle(t, x, y):
x = x*xScale
y = y*yScale#放大倍数显示
drawLine(t, x-5, 0, x-5, y)
drawLine(t, x-5, y, x+5, y)
drawLine(t, x+5, y, x+5, 0)
drawLine(t, x+5, 0, x-5, 0)
#绘制多个柱体
def drawBar(t):
for i in range(count):
drawRectangle(t, i+1, data[i])
################# Turtle End ####################
#对文本的每一行计算词频的函数
def processLine(line, wordCounts):
#用空格替换标点符号
line = replacePunctuations(line)
#从每一行获取每个词
words = line.split()
for word in words:
if word in wordCounts:
wordCounts[word] += 1
else:
wordCounts[word] = 1
#空格替换标点的函数
def replacePunctuations(line):
for ch in line:
if ch in"~@#$%^&*()_-+=<>?/,.:;{}[]|\'""":
line = line.replace(ch, "")
return line
def main():
#用户输入一个文件名
filename = input("enter a filename:").strip()
infile = open(filename, "r")
#建立用于计算词频的空字典
wordCounts = {}
for line in infile:
processLine(line.lower(), wordCounts)
#从字典中获取数据对
pairs = list(wordCounts.items())
#列表中的数据对交换位置,数据对排序
items = [[x,y]for (y,x)in pairs]
items.sort()
#输出count个数词频结果
for i in range(len(items)-1, len(items)-count-1, -1):
print(items[i][1]+"\t"+str(items[i][0]))
data.append(items[i][0])
words.append(items[i][1])
infile.close()
#根据词频结果绘制柱状图
turtle.title('词频结果柱状图')
turtle.setup(900, 750, 0, 0)
t = turtle.Turtle()
t.hideturtle()
t.width(3)
drawGraph(t)
#调用main()函数
if __name__ == '__main__':
main()
【运行结果】
【实例二】使用字典结构优化程序5.3.2
程序5.6.2
#利用字典将两个通讯录文本合并为一个文本
def main():
ftele2=open('TeleAddressBook.txt','rb')
ftele1=open('EmailAddressBook.txt','rb')
ftele1.readline()#跳过第一行
ftele2.readline()
lines1 = ftele1.readlines()
lines2 = ftele2.readlines()
dic1 = {} #字典方式保存
dic2 = {}
for line in lines1:#获取第一个本文中的姓名和电话信息
elements = line.split()
#将文本读出来的bytes转换为str类型
dic1[elements[0]] =str(elements[1].decode('gbk'))
for line in lines2:#获取第二个本文中的姓名和电话信息
elements = line.split()
dic2[elements[0]] = str(elements[1].decode('gbk'))
###开始处理###
lines = []
lines.append('姓名\t 电话 \t 邮箱\n')
for key in dic1:
s= ''
if key in dic2.keys():
s ='\t'.join([str(key.decode('gbk')), dic1[key], dic2[key]])
s += '\n'
else:
s ='\t'.join([str(key.decode('gbk')), dic1[key], str(' ----- ')])
s += '\n'
lines.append(s)
for key in dic2:
s= ''
if key not in dic1.keys():
s ='\t'.join([str(key.decode('gbk')), str(' ----- '), dic2[key]])
s += '\n'
lines.append(s)
ftele3 = open('AddressBook.txt', 'w')
ftele3.writelines(lines)
ftele3.close()
ftele1.close()
ftele2.close()
print("The addressBooks aremerged!")
if __name__ == "__main__":
main()
- Python 程序设计语言 笔记(六)
- Python 程序设计语言 笔记(一)
- Python 程序设计语言 笔记(二)
- python 程序设计语言 笔记(三)
- Python 程序设计语言 笔记(四)
- Python 程序设计语言 笔记(五)
- Python 程序设计语言 笔记(七)
- Python 程序设计语言 笔记(八)
- C程序设计语言整理笔记(六)结构
- 《C++程序设计语言》笔记之六
- python笔记(六)
- C程序设计语言(六)UNIX系统接口
- python学习笔记(六)
- python 学习笔记(六)
- Python学习笔记(六)
- Python学习笔记(六)
- 《Python编程》笔记(六)
- python学习笔记(六)
- 如何自己动手实现 KVO
- C#实例之计算字符串中不同字符的个数
- C++虚函数分析[2]--虚函数介绍
- PHP的session存放路径及其配置session.save_path
- Bloom Filter算法和实现
- Python 程序设计语言 笔记(六)
- 水池数目
- Java并发编程系列之二十:Fork/Join框架
- 关于有偿提供拼图响应式后台的通知
- LeetCode(26)-Binary Tree Level Order Traversal II
- C-mini 程序设计语言的设计与实现
- activity-alias
- 进程地址空间
- TCP协议的学习(二)TCP头部信息