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


0 0
原创粉丝点击