【Python】第七弹---Python基础进阶:深入字典操作与文件处理技巧

✨个人主页:熬夜学编程的小林

💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】【Linux系统编程】【MySQL】【Python】

目录

1、字典

1.1、字典是什么

1.2、创建字典

[1.3、查找 key](#1.3、查找 key)

1.4、新增/修改元素

1.5、删除元素

1.6、遍历字典元素

[1.7、取出所有 key 和 value](#1.7、取出所有 key 和 value)

[1.8、合法的 key 类型](#1.8、合法的 key 类型)

1.9、小结

2、文件

2.1、文件是什么

2.2、文件路径

2.3、文件操作

2.3.1、打开文件

2.3.2、关闭文件

2.3.3、写文件

2.3.4、读文件

2.4、关于中文的处理

2.5、使用上下文管理器


1、字典

1.1、字典是什么

字典是一种存储 键值对 的结构.

啥是键值对? 这是计算机/生活中一个非常广泛使用的概念.

键(key) 和 值(value) 进行一个一对一的映射 , 然后就可以根据键, 快速找到值.

  • 举个栗子, 学校的每个同学, 都会有一个唯一的学号.
  • 知道了学号, 就能确定这个同学.
  • 此处 "学号" 就是 "键", 这个 "同学" 就是 "值".

1.2、创建字典

创建一个空的字典. 1、使用 { } 表示字典. 2、使用dict()函数创建字典,适用动态创建情况。

复制代码
a = {} # 创建一个空字典
b = dict() # 使用函数创建字典
print(type(a))
print(type(b))
  • 也可以在创建的同时指定初始值

  • 键值对之间使用 , 分割 , 键和值之间使用 : 分割. (冒号后面推荐加一个空格).

  • 使用 print 来打印字典内容

    student = {'id': 1,'name': 'zhangsan'} # 创建字典并初始化
    print(student) # 打印字典数据

  • 为了代码更规范美观, 在创建字典的时候往往会把多个键值对, 分成多行来书写.

    student = {
    'id': 1,
    'name': 'zhangsan'
    } # 创建字典并分行初始化
    print(student) # 打印字典数据

  • 最后一个键值对, 后面可以写 , 也可以不写.

    student = {
    'id': 1,
    'name': 'zhangsan', # 最后一个键值对加,
    } # 创建字典并分行初始化
    print(student) # 打印字典数据

1.3、查找 key

使用 in 可以判定 key 是否在 字典 中存在. 返回布尔值.

复制代码
student = {
    'id': 1,
    'name': 'zhangsan',
}
print('id' in student)    # 判断key值id是否存在
print('score' in student) # 判断key值score是否存在

使用 [ ] 通过类似于取下标的方式, 获取到元素的值 . 只不过此处的 "下标" 是 key . (可能是整数, 也可能是字符串等其他类型).

复制代码
student = {
    'id': 1,
    'name': 'zhangsan',
}
print(student['id'])   # key值id对应的值
print(student['name']) # key值name对应的值

如果 key 在字典中不存在, 则会抛出异常.

复制代码
student = {
    'id': 1,
    'name': 'zhangsan',
}
print(student['score'])   # key值score对应的值,不存在则抛异常

1.4、新增/修改元素

使用 [ ] 可以根据 key 来新增/修改 value.

如果 key 不存在 , 对取下标操作赋值, 即为新增键值对

复制代码
student = {
    'id': 1,
    'name': 'zhangsan'
}

print(student)
student['score'] = 90 #key值score不存在则新增键值对
print(student)

如果 key 已经存在 , 对取下标操作赋值, 即为修改键值对的值.

复制代码
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}

print(student)
student['score'] = 90 # key值已经存在,即对键值对值进行修改
print(student)

1.5、删除元素

使用pop 方法根据 key 删除对应的键值对.

复制代码
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}

print(student)
student.pop('score') # 删除key值为score的键值对
print(student)

1.6、遍历字典元素

直接使用 for 循环能够获取到字典中的所有的 key, 进一步的就可以取出每个值了.

复制代码
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}

for key in student:
    print(key,student[key])

1.7、取出所有 key 和 value

使用keys 方法可以获取到字典中的所有的 key

复制代码
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}

print(student.keys()) # 使用keys获取所有key值
  • 此处 dict_keys 是一个特殊的类型, 专门用来表示字典的所有 key. 大部分元组支持的操作对于dict_keys 同样适用.

使用 values 方法可以获取到字典中的所有 value

复制代码
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}

print(student.values()) # 使用values获取所有value值
  • 此处 dict_values 也是一个特殊的类型, 和 dict_keys 类似.

使用items 方法可以获取到字典中所有的键值对.

复制代码
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}

print(student.items()) # 使用items获取所有键值对

1.8、合法的 key 类型

不是所有的类型都可以作为字典的 key.

字典本质上是一个 哈希表 , 哈希表的 key 要求是 "可哈希的", 也就是可以计算出一个哈希值.

  • 可以使用 hash 函数计算某个对象的哈希值.

  • 但凡能够计算出哈希值的类型, 都可以作为字典的 key.

    print(hash(0)) # 计算hash值
    print(hash(3.14))
    print(hash('hello'))
    print(hash(True))
    print(hash(()))

列表无法计算哈希值.

复制代码
print(hash([1,2,3])) # 列表不能计算hash值

字典也无法计算哈希值

复制代码
print(hash({'id': 1})) # 字典不能计算hash值

1.9、小结

字典也是一个常用的结构. 字典的所有操作都是围绕 key 来展开的.

需要表示 "键值对映射" 这种场景时就可以考虑使用字典.

2、文件

2.1、文件是什么

变量是把数据保存到内存中 . 如果程序重启/主机重启, 内存中的数据就会丢失.

要想能让数据被持久化存储 , 就可以把数据存储到硬盘中 . 也就是在 文件 中保存.

在 Windows "此电脑" 中, 看到的内容都是 文件.

通过文件的后缀名, 可以看到文件的类型. 常见的文件的类型如下:

  • 文本文件 (txt)
  • 可执行文件 (exe, dll)
  • 图片文件 (jpg, gif)
  • 视频文件 (mp4, mov)
  • office 文件 (.ppt, docx)
  • ......

我们主要研究最简单的文本文件.

2.2、文件路径

一个机器上, 会存在很多文件, 为了让这些文件更方面的被组织, 往往会使用很多的 "文件夹"(也叫做目录)来整理文件 .

实际一个文件往往是放在一系列的目录结构之中的.
为了方便确定一个文件所在的位置 , 使用 文件路径 来进行描述.

例如, 上述截图中的 QQ.exe 这个文件, 描述这个文件的位置 , 就可以使用路径D:\program\qq\Bin\QQ.exe 来表示.

  • D: 表示 盘符. 不区分大小写.
  • 每一个 \ 表示一级目录. 当前 QQ.exe 就是放在 "D 盘下的 program 目录下的 qq 目录下的 Bin 目录中" .
  • 目录之间的分隔符, 可以使用 \ 也可以使用 / . 一般在编写代码的时候使用 / 更方便.

上述以 盘符 开头的路径 , 我们也称为 绝对路径 .

除了绝对路径之外, 还有一种常见的表示方式是 相对路径 . 相对路径需要先指定一个基准目录 , 然后
以基准目录为参照点, 间接的找到目标文件 . 咱们课堂上暂时不详细介绍.

描述一个文件的位置, 使用 绝对路径相对路径 都是可以的. 对于新手来说, 使用 绝对路径 更简
单更好理解, 也不容易出错.

2.3、文件操作

使用文件 , 主要是通过文件来保存数据 , 并且在后续把保存的数据读取出来 .

但是要想读写文件, 需要先 "打开文件" , 读写完毕之后还要 "关闭文件".

2.3.1、打开文件

使用内建函数 open 打开一个文件.

复制代码
f = open('d:/test.txt', 'r')  # 以读的方式打开文件
  • 第一个参数是一个字符串 , 表示要打开的文件路径
  • 第二个参数是一个字符串 , 表示打开方式 . 其中r 表示按照读方式打开. w 表示按照写方式打开. a表示追加写方式打开.
  • 如果打开文件成功, 返回一个文件对象. 后续的读写文件操作都是围绕这个文件对象展开.
  • 如果打开文件失败 (比如路径指定的文件不存在), 就会抛出异常.

2.3.2、关闭文件

使用 close 方法关闭已经打开的文件.

复制代码
f.close() # 关闭文件
  • 使用完毕的文件要记得及时关闭!

一个程序能同时打开的文件个数, 是存在上限的.

复制代码
flist = []
count = 0
while True:
    f = open('d:/test.txt', 'r') # 需要现在d盘路径下创建一个test.txt文件
    flist.append(f) # 尾插文件对象
    count += 1
    print(f'count = {count}')
  • 如上面代码所示, 如果一直循环的打开文件, 而不去关闭的话, 就会出现上述报错.
  • 当一个程序打开的文件个数超过上限, 就会抛出异常.

注意: 上述代码中, 使用一个列表来保存了所有的文件对象 . 如果不进行保存, 那么 Python 内置的垃

圾回收机制, 会在文件对象销毁的时候自动关闭文件.

但是由于垃圾回收操作不一定及时, 所以我们写代码仍然要考虑手动关闭, 尽量避免依赖自动关闭.

2.3.3、写文件

文件打开之后, 就可以写文件了.

  • 写文件, 要使用写方式打开, open 第二个参数设为 'w'

  • 使用 write 方法写入文件.

    f = open('d:/test.txt', 'w') # 以写的方式打开文件
    f.write('hello') # 向文件中写入hello字符串
    f.close() # 关闭文件

  • 用记事本打开文件, 即可看到文件修改后的内容.

如果是使用 'r' 方式打开文件, 则写入时会抛出异常.

复制代码
f = open('d:/test.txt', 'r')  # 以读的方式打开文件
f.write('hello')  # 向文件中写入hello字符串
f.close()  # 关闭文件

使用 'w' 一旦打开文件成功, 就会清空文件原有的数据 .
使用 'a' 实现 "追加写", 此时原有内容不变 , 写入的内容会存在于之前文件内容的末尾.

复制代码
f = open('d:/test.txt', 'w')  # 以写的方式打开文件
f.write('hello')  # 向文件中写入hello字符串
f.close()   # 关闭文件

f = open('d:/test.txt', 'a')  # 以追加的方式打开文件
f.write(' world')   # 向文件中追加写入 world
f.close()  # 关闭文件

针对已经关闭的文件对象进行写操作, 也会抛出异常.

复制代码
f = open('d:/test.txt', 'w')
f.write('hello')  # 向文件写入hello字符串
f.close()  # 关闭文件
f.write('world')  # 文件关闭之后写入文件内容抛异常

2.3.4、读文件

读文件内容需要使用 'r' 的方式打开文件

使用 read 方法完成读操作. 参数表示 "读取几个字符"

  • 注意:读文件之前需要先有该文件
复制代码
f = open('d:/test.txt', 'r')  # 以读的方式打开文件
result = f.read(2)  # 读取两个字符
print(result)
f.close()   # 关闭文件
  • 如果文件是多行文本, 可以使用 for 循环一次读取一行.

先构造一个多行文件.

复制代码
f = open('d:/test.txt', 'r')
for line in f:
    print(f'line = {line}')  # 以行读取文件
f.close()

注意: 由于文件里每一行末尾都自带换行符 , print 打印一行的时候又会默认加上一个换行符 , 因此
打印结果看起来之间存在空行 .
使用 print(f'line = {line}', end='') 手动把 print 自带的换行符去掉.

复制代码
f = open('d:/test.txt', 'r')
for line in f:
    print(f'line = {line}', end='')  # 以行读取文件,并手动去掉换行
f.close()

使用 readlines 直接把文件整个内容读取出来, 返回一个列表. 每个元素即为一行.

复制代码
f = open('d:/test.txt', 'r')
lines = f.readlines()  # 读取整个文件内容
print(lines)
f.close()
  • 此处的 \n 即为换行符.

2.4、关于中文的处理

当文件内容存在中文的时候, 读取文件内容不一定就顺利.

同样上述代码, 有的uu执行时可能会出现异常

也有的uu可能出现乱码.

计算机表示中文的时候, 会采取一定的编码方式, 我们称为 "字符集"

  • 所谓 "编码方式 " , 本质上就是使用数字表示汉字.
  • 我们知道, 计算机只能表示二进制数据. 要想表示英文字母, 或者汉字, 或者其他文字符号, 就都要通过编码.
  • 最简单的字符编码就是 ascii. 使用一个简单的整数就可以表示英文字母和阿拉伯数字.
  • 但是要想表示汉字, 就需要一个更大的码表.
  • 一般常用的汉字编码方式, 主要是 GBKUTF-8

必须要保证文件本身的编码方式, 和 Python 代码中读取文件使用的编码方式匹配, 才能避免出现上述问题.

  • Python3 中默认打开文件的字符集跟随系统, 而 Windows 简体中文版的字符集采用了 GBK, 所以如果文件本身是 GBK 的编码, 直接就能正确处理.
  • 如果文件本身是其他编码(比如 UTF-8), 那么直接打开就可能出现上述问题

使用记事本打开文本文件 , 在 "菜单栏" -> "文件" -> "另存为" 窗口中, 可以看到当前文件的编码方式.

  • 如果此处的编码为 ANSI , 则表示 GBK 编码.
  • 如果此处为 UTF-8 , 则表示 UTF-8 编码.

此时修改打开文件的代码, 给 open 方法加上 encoding 参数 , 显式的指定为和文本相同的字符集, 问题即可解决.

复制代码
f = open('d:/test.txt', 'r', encoding='utf8')

2.5、使用上下文管理器

打开文件之后, 是容易忘记关闭的. Python 提供了 上下文管理器 , 来帮助程序猿自动关闭文件.

  • 使用 with 语句打开文件.

  • 当 with 内部的代码块执行完毕后, 就会自动调用关闭方法.

    with open('d:/test.txt', 'r', encoding='utf8') as f:
    lines = f.readlines()
    print(lines)

相关推荐
layman05288 分钟前
CSS选择器
前端·css
Dovis(誓平步青云)10 分钟前
【数据结构】·励志大厂版(复习+刷题):二叉树
c语言·数据结构·经验分享·笔记·学习·算法·学习方法
越城11 分钟前
算法效率的钥匙:从大O看复杂度计算 —— C语言数据结构第一讲
c语言·开发语言·数据结构·算法
姜太小白13 分钟前
【前端】jQuery 对数据进行正序排列
前端·javascript·jquery
姜行运14 分钟前
数据结构【堆和链式结构】
数据结构·算法·c#
没有梦想的咸鱼185-1037-166314 分钟前
解锁空间数据新质生产力暨:AI(DeepSeek、ChatGPT)、Python、ArcGIS Pro多技术融合下的空间数据分析、建模与科研绘图及论文写作
人工智能·python·深度学习·机器学习·arcgis·chatgpt·数据分析
极小狐1 小时前
极狐GitLab 议题权重有什么作用?
开发语言·数据库·chrome·c#·gitlab
z_mazin1 小时前
用户行为检测技术解析:从请求头到流量模式的对抗与防御
python·网络爬虫
狐凄2 小时前
Python实例题:使用Pvthon3编写系列实用脚本
java·网络·python
艾小逗3 小时前
vue3中的effectScope有什么作用,如何使用?如何自动清理
前端·javascript·vue.js