【Python】4.字典和文件

发布于:2025-05-31 ⋅ 阅读:(16) ⋅ 点赞:(0)

一、字典

1、字典是什么?

字典是一种存储 键值对 的结构。
啥是键值对? 这是计算机/生活中一个非常广泛使用的概念。
把 键(key) 和 值(value) 进行一个一对一的映射,然后就可以根据键,快速找到值。

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

2、创建字典

  • 创建一个空的字典,有两种方式,第一种使用 { } 表示字典,第二种可以使用dict()
a = { }
b = dict()

print(type(a))
print(type(b))

运行结果:

注意:

  • 也可以在创建的同时指定初始值。
  • 键值对之间使用,分割,键和值之间使用 : 分割。(冒号后面推荐加一个空格)。
  • 使用 print 来打印字典内容。
student = { 'id': 1, 'name': 'zhangsan' }
print(student)

运行结果:

  • 为了代码更规范美观,在创建字典的时候往往会把多个键值对,分成多行来书写。
student = {
    'id': 1,
    'name': 'zhangsan'
}

3、查找 key

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

student = {
    'id': 1,
    'name': 'zhangsan'
}

print('id' in student)
print('score' in student)

运行结果:

  • 使用 [ ]通过类似于取下标的方式,获取到元素的值。
    只不过此处的 “下标” 是 key。(可能是整数,也可能是字符串等其他类型)。
student = {
    'id': 1,
    'name': 'zhangsan',
}

print(student['id'])
print(student['name'])

运行结果:

  • 如果 key 在字典中不存在,则会抛出异常。
student = {
    'id': 1,
    'name': 'zhangsan',
}

print(student['score'])

运行结果:

4、新增/修改元素

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

  • 如果 key 不存在,对取下标操作赋值,即为新增键值对。
student = {
    'id': 1,
    'name': 'zhangsan',
}

student['score'] = 90
print(student)

运行结果:

  • 如果 key 已经存在,对取下标操作赋值,即为修改键值对的值。
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}

student['score'] = 90
print(student)

运行结果:

5、删除元素

  • 使用 pop 方法根据 key 删除对应的键值对。
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}

student.pop('score')
print(student)

运行结果:

6、遍历字典元素

  • 直接使用 for 循环能够获取到字典中的所有的 key,进一步的就可以取出每个值。
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}

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

运行结果:

7、取出所有 key 和 value

  • 使用 keys 方法可以获取到字典中的所有的 key。
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}

print(student.keys())

运行结果:

此处的dict_keys是一个特殊的类型,专门用来表示字典的所有 key。大部分元组支持的操作对于dict_keys同样适用。

  • 使用 values 方法可以获取到字典中的所有 value。
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}

print(student.values())

运行结果:

此处 dict_values 也是一个特殊的类型,和 dict_keys 是类似的。

  • 使用 items 方法可以获取到字典中所有的键值对。
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}
print(student.items())

运行结果:

此处 dict_items 也是一个特殊的类型, 和 dict_keys 是类似的。

8、合法的 key 类型

不是所有的类型都可以作为字典的 key。
字典本质上是一个 哈希表,哈希表的 key 要求是 “可哈希的”,也就是可以计算出一个哈希值。

  • 可以使用 hash 函数计算某个对象的哈希值。
  • 但凡能够计算出哈希值的类型,都可以作为字典的 key。
print(hash(0))
print(hash(3.14))
print(hash('hello'))
print(hash(True))
print(hash(()))  # ( )是一个空的元组

运行结果:

  • 列表无法计算哈希值。
print(hash([1, 2, 3]))

报错:

  • 字典也无法计算哈希值。
print(hash({ 'id': 1 }))

报错:

小结

字典也是一个常用的结构,字典的所有操作都是围绕 key 来展开的。
需要表示 “键值对映射” 这种场景时就可以考虑使用字典。

二、文件

1、文件是什么?

变量是把数据保存到内存中,如果程序重启/主机重启,内存中的数据就会丢失。
要想能让数据被持久化存储,就可以把数据存储到硬盘中。也就是在文件中保存。

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

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

这里主要研究最简单的文本文件。

2、文件路径

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

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

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

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

上述以盘符开头的路径,我们称为绝对路径
除了绝对路径之外,还有一种常见的表示方式是 相对路径
相对路径需要先指定一个基准目录,然后以基准目录为参照点,间接的找到目标文件。
描述一个文件的位置,使用 绝对路径相对路径 都是可以的。对于新手来说,使用 绝对路径 更简单更好理解,也不容易出错。

3、文件操作

要使用文件,主要是通过文件来保存数据,并且在后续把保存的数据读取出来。
但是要想读写文件,需要先 “打开文件”,读写完毕之后还要 “关闭文件”。

1)打开文件

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

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

2)关闭文件

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

f.close()

文件使用完毕后要记得及时关闭!

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

flist = []
count = 0
while True:
    f = open('d:/test.txt', 'r')
    flist.append(f)
    count += 1
    print(f'count = {count}')

报错:
在这里插入图片描述

如上面代码所示,如果一直循环的打开文件,而不去关闭的话,就会出现上述报错。
当一个程序打开的文件个数超过上限,就会抛出异常。
注意: 上述代码中,使用一个列表来保存了所有的文件对象。如果不进行保存,那么 Python 内置的垃圾回收机制,会在文件对象销毁的时候自动关闭文件。但是由于垃圾回收操作不一定及时,所以我们写代码仍然要考虑手动关闭,尽量避免依赖自动关闭。

3)写文件

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

  • 写文件,要使用写方式打开,open 第二个参数设为 ‘w’。
  • 使用 write 方法写入文件。
f = open('d:/test.txt', 'w')
f.write('hello')
f.close()

运行后查看文件内容:
在这里插入图片描述

用记事本打开d盘目录下的test.txt文件,即可看到文件修改后的内容。

  • 如果是使用 'r' 方式打开文件,则写入时会抛出异常。
f = open('d:/test.txt', 'r')
f.write('hello')
f.close()

报错:
在这里插入图片描述

  • 使用 'w' 一旦打开文件成功,就会清空文件原有的数据。
f = open('d:/test.txt', 'w')
f.write('hello')
f.close()
  • 使用 'a' 实现 “追加写”,此时原有内容不变,写入的内容会存在于之前文件内容的末尾。
f = open('d:/test.txt', 'a')
f.write('world')
f.close()

运行后查看文件内容:
在这里插入图片描述

  • 针对已经关闭的文件对象进行写操作,也会抛出异常。
f = open('d:/test.txt', 'w')
f.write('hello')
f.close()
f.write('world')

运行结果:

4)读文件

  • 读文件内容需要使用 'r' 的方式打开文件。
  • 使用 read 方法完成读操作,参数表示读取几个字符
f = open('d:/test.txt', 'r')
result = f.read(2)
print(result)
f.close()

运行结果:
在这里插入图片描述

  • 如果文件是多行文本,可以使用 for 循环一次读取一行。

先构造一个多行文件。
在这里插入图片描述

再按行进行读取:

f = open('d:/test.txt', 'r',encoding='utf - 8')
for line in f:
    print(line)
f.close()

运行结果:

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

再次运行结果:

  • 使用 readlines 直接把文件整个内容读取出来, 返回一个列表. 每个元素即为一行.
f = open('d:/test.txt', 'r')
lines = f.readlines()
print(lines)
f.close()

运行结果:

在这里插入图片描述
此处的 \n 即为换行符.

4、关于中文的处理

当文件内容存在中文的时候,读取文件内容不一定就顺利。
同样上述代码,读取文件时可能会出现异常。

在这里插入图片描述

也有可能出现乱码。
在这里插入图片描述

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

所谓 “编码方式”,本质上就是使用数字表示汉字。
我们知道,计算机只能表示二进制数据,要想表示英文字母,或者汉字,或者其他文字符号,就都要通过编码。
最简单的字符编码就是 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')

PS:字符编码问题,是编程中一类比较常见,又比较棘手的问题。需要对于字符编码有一定的理解,才能从容应对。
可以参考腾讯官方账号发表的帖子,详细介绍了里面的细节。https://zhuanlan.zhihu.com/p/46216008

5、使用上下文管理器

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

  • 使用 with 语句打开文件。
  • 当 with 内部的代码块执行完毕后,就会自动调用关闭方法。
with open('d:/test.txt', 'r', encoding='utf8') as f:
    lines = f.readlines()
    print(lines)

运行结果:
在这里插入图片描述