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

原文地址:https://blog.csdn.net/longteng007/article/details/51073681

第五周 文件与字典

       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


  
  
  1. def main():
  2. fname = input(“Enter filename:”)
  3. infile = open(fname.“r”)
  4. data = infile.read()
  5. print(data)
  6. for i in range( 5):
  7. line = infile.readline()
  8. print(line[: -1])
  9. main()

               ② 文件写入:

操作名称

操作含义

write()

  把含有本文数据或二进制数据块的字符串写入文件中  

  writelines()  

针对列表操作,接受一个字符串列表作为参数

将它们写入文件,并且行结束符不会被自动加入

                           例:

>>>> outfile = open(“outfile.txt”,”w”)
  
  
>>>> outfile.writelines([“Hello”, ” ”, ”world”])
  
  
>>>> outfile.close()
  
  
>>>> infile = open(“outfile.txt”, “r”)
  
  
>>>> infile.read()
  
  
‘Helloworld’
  
  


               ③ 文件遍历:如: 拷贝文件,根据数据文件定义行走路径,将文件由一种编码转换为另外一种编码

                                   通用代码框架:


  
  
  1. file = open(someFile, ”r”)
  2. for line in file.readlines(): # 可简化为 for line in file:
  3. #处理一行文件内容
  4. file.close()
 
 

               例:文件拷贝

程序5.2.2

  
  

  
  
  1. def main():
  2. # 用户输入文件名
  3. f1 = input( "Enter a soucefile:").strip()
  4. f2 = input( "Enter a soucefile:").strip()
  5. # 打开文件
  6. infile = open(f1, "r")
  7. outfile = open(f2, "w")
  8. # 拷贝数据
  9. countLines = countChars = 0
  10. for line in infile:
  11. countLines += 1
  12. countChars += len(line)
  13. outfile.write(line)
  14. print(countLines, "linesand",countChars, "chars copied")
  15. infile.close()
  16. outfile.close()
  17. 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】

输入:数据文件

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

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

【程序实现】


  
  
  1. 程序 5.3 .1
  2. # 根据数据文件在窗口中动态路径绘制
  3. import turtle
  4. def main():
  5. # 设置窗口信息
  6. turtle.title( '数据驱动的动态路径绘制')
  7. turtle.setup( 800, 800, 0, 0)
  8. # 设置画笔
  9. pen =turtle.Turtle()
  10. pen.color( "red")
  11. pen.width( 5)
  12. pen.shape( "turtle")
  13. pen.speed( 5)
  14. # 读取文件
  15. result = []
  16. file = open( "data.txt", "r")
  17. for line in file:
  18. result.append(list(map(float, line.split( ','))))
  19. print(result)
  20. for i inrange(len(result)):
  21. pen.color(result[i][ 3],result[i][ 4],result[i][ 5])
  22. pen.fd(result[i][ 0])
  23. if result[i][ 1]:
  24. pen.rt(result[i][ 2])
  25. else:
  26. pen.lt(result[i][ 2])
  27. pen.goto( 0, 0)
  28. if __name__ == '__main__':
  29. main()

【运行结果】


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

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

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

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


【程序实现】


  
  
  1. 程序 5.3 .2
  2. def main():
  3. ftele1 = open( 'TeleAddressBook.txt', 'rb')
  4. ftele2 = open( 'EmailAddressBook.txt', 'rb')
  5. ftele1.readline() # 跳过第一行
  6. ftele2.readline()
  7. lines1 = ftele1.readlines()
  8. lines2 = ftele2.readlines()
  9. list1_name = []
  10. list1_tele = []
  11. list2_name = []
  12. list2_email = []
  13. for line in lines1: # 获取第一个文本中的姓名和电话信息
  14. elements = line.split()
  15. list1_name.append(str(elements[ 0].decode( 'gbk')))
  16. list1_tele.append(str(elements[ 1].decode( 'gbk')))
  17. # 将文本读出来的bytes转换为str类型
  18. for line in lines2: # 获取第二个文本中的姓名和邮件信息
  19. elements = line.split()
  20. list2_name.append(str(elements[ 0].decode( 'gbk')))
  21. list2_email.append(str(elements[ 1].decode( 'gbk')))
  22. # 开始处理 #
  23. lines = []
  24. lines.append( '姓名\t 电话 \t 邮箱\n')
  25. # 按索引方式遍历姓名列表1
  26. for i in range(len(list1_name)):
  27. s = ''
  28. if list1_name[i] in list2_name:
  29. j = list2_name.index(list1_name[i])
  30. # 找到姓名列表1对应列表2中姓名
  31. s = '\t'.join([list1_name[i],list1_tele[i], list2_email[j]])
  32. s += '\n'
  33. else:
  34. s = '\t'.join([list1_name[i],list1_tele[i], str( ' ----- ')])
  35. s += '\n'
  36. lines.append(s)
  37. # 处理姓名列表2中剩余的姓名
  38. for i in range(len(list2_name)):
  39. s = ''
  40. if list2_name[i] not in list1_name:
  41. s = '\t'.join([list2_name[i],str( ' ----- '), list2_email[i]])
  42. s += '\n'
  43. lines.append(s)
  44. ftele3 = open( 'AddressBook.txt', 'w')
  45. ftele3.writelines(lines)
  46. ftele3.close()
  47. ftele1.close()
  48. ftele2.close()
  49. print( "The addressBooks aremerged!")
  50. if __name__ == "__main__":
  51. 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()


猜你喜欢

转载自blog.csdn.net/qq_36369267/article/details/82831631