Python 程序设计语言 笔记(六)

时间:2022-08-25 23:38:08

第五周 文件与字典

       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库来动态绘制图形路径

Python 程序设计语言 笔记(六)

元素1:路径前进像素数

元素2:转动方向,0为左,1为右

元素3:转动角度

元素4-6:绘制颜色的RGB值

例:第一行 — 绘制路径前进300个像素,向左转动144度,路径线段颜色为红色

【IPO】

输入:数据文件

处理:读取数据文件,并根据数据内容和要求绘制路径

输出:构建窗口,并输出图形

【程序实现】

程序5.3.1
# 根据数据文件在窗口中动态路径绘制
import turtle
def 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()

【运行结果】

Python 程序设计语言 笔记(六)

【文件实例二】多文件读写 — 合并邮箱簿和电话簿文件

【IPO】输入:电话簿、邮箱地址簿文件

            处理:将两个文件内容进行合并

            输出:合并后的包含电话和邮箱地址的文件

Python 程序设计语言 笔记(六)

【程序实现】

程序5.3.2
def 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

Python 程序设计语言 笔记(六)

              (2)访问字典中的值,格式:

dictionaryName[key]

Python 程序设计语言 笔记(六)

                     若访问的值不存在,则返回错误信息

              (3)删除字典中的一项,格式:

del dictionaryName[key]

              (4)字典的遍历,格式:

for key in dictionaryName:

                           print(key + : +str(dictionaryName[key]))

Python 程序设计语言 笔记(六)

             可遍历的内容:① 键       ② 值     ③ 项     ④ 键值对

                     for keys/values/itemsin dictionaryName.keys/values/items():

print(key/value/item)

                for item, value in adict.items():

                     print(item,value)

          (5)一个键是否在字典中:in或者not inPython 程序设计语言 笔记(六)

  (6)字典不提供拼接和重复操作方法,其余操作符都可正常使用,字典是无序的

  (7)字典方法:

方法名称

方法含义

keys():tuple

返回一个包含字典所有key的列表

values():tuple

  返回一个包含字典所有value的列表  

items():tuple

返回一个包含所有键值的列表

clear():None

删除字典中的所有项目

  get(key):value  

返回字典中key对应的值

pop(key):val

删除并返回字典中key对应的值

update(tuple)

将字典中的键值添加到字典中

Python 程序设计语言 笔记(六)

5.6 字典实例

【实例一】“统计词频”问题:

【问题描述】统计文章重复词语,有助于搜索引擎对网络信息的检索与归档

【IPO】 输入:从文件中读取一篇英文文章

              处理:统计文件中每个单词的出现频率

              输出:将最常出现的10个单词及出现次数,以下图表形式输出

Python 程序设计语言 笔记(六)

【分析】①建立用于词频计算的空字典,对文本的每一行计算词频

② 从字典中获取数据对到列表中,对列表中的数据交换位置并排序

③ 用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()

【运行结果】

Python 程序设计语言 笔记(六)

【实例二】使用字典结构优化程序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()