百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

Python之容器:字典(dict)就是哈希表换个马甲?

liuian 2025-02-19 12:55 32 浏览

引言

从上一篇文章开始,开始了Python中常用的数据结构,也就是容器类的介绍,上一篇文章简要介绍了列表的使用,这一篇文章准备介绍一下Python中字典(dict)的使用。

本文的主要内容大概如下:
1、简要介绍Python中字典的特点
2、遍历字典的几种方法
3、字典中的常用方法
4、字典推导式

Python中字典的特点

Python中的字典(dict)是一种非常强大的数据结构,对应到其他编程语言中的“哈希表”这种容器类型。

Python中的字典有如下特点:
1、键值对存储:便于通过键值快速检索、定位数据,比列表的索引方式更加方便。
2、关于顺序:在Python3.7之前,字典中的键值对是无序的。从Python3.7开始,字典中的键值对保持插入的顺序;但是,需要留意的是:自Python3.7开始,dict类型正式“有顺序”了,不过只是保留键的插入顺序。你不能随意重新排列dict中的键。
3、键的不变性:字典中的键必须是不可变的数据类型,比如(字符串、数字、元组),因为底层存储需要通过键进行哈希;值的类型是任意的。
4、可变性:字典是可变的,可以随时修改、添加和删除键值对。

字典的遍历

关于字典中最常用的一个操作,就是对字典的遍历,在Python中有几种常用的遍历方式,可以根据实际需要自行选择:
首先生成测试数据:
还是以人员信息为例,这次我们使用嵌套字典的方式存储,字典的key为name,字典的值为完整的人员信息的字典,包含name、age、gender、height

from faker import Faker
from rich import print
fk = Faker('zh_CN')

# 人员信息的测试数据
persons = {}
for _ in range(10):
    name = fk.unique.name()
    persons[name] = {'name': name, 'age': fk.random_int(1, 150), 'gender': fk.passport_gender(), 'height': fk.random_int(130, 200)}

print(persons)

执行结果:


需要注意的是,每次执行程序,生成的测试数据都是不一样的,所以,上面的执行结果只是一个示例。

方法1:遍历字典的键

for k in persons.keys():
    print(k)

for k in persons:
    print(k)

通过keys()方法进行遍历,与直接对persons进行遍历是一样的。

方法2:遍历字典的值

for p in persons.values():
    print(p) 

方法3:遍历字典的键值对:

for k, v in persons.items():
    print(f"key: {k}, value: {v}")

字典常用方法

关于字典的增、删、改的操作比较简单,这里就不列举了。下面就几个在实际应用中,比较实用的方法做一下简单介绍。
1、根据可迭代对象初始化一个字典:fromkeys()
在实际使用中,有些数据可能是以其他形式存储的,我们在处理过程中,可能首先需要初始化一个字典,然后进行更进一步的处理:
比如,游戏开始之初,对玩家积分进行一个初始化的操作,后续根据游戏进度进行积分的动态更新

players = ['刘备', '关羽', '张飞', '赵云', '诸葛亮']
scores = dict.fromkeys(players, 0)
print(scores)
scores['赵云'] += 10
scores['诸葛亮'] += 100
print(scores)

执行结果:

2、获取字典中的值 get()
实际使用中,要通过键获取对应的值有两种方式:
1)通过[key]的形式
2)通过get()方法
两者的不同在于,[key]索引的形式,当键值不存在时会抛异常;get()方法,键值不存在时默认返回None,也可以设置指定的默认值。

players = ['刘备', '关羽', '张飞', '赵云', '诸葛亮']
scores = dict.fromkeys(players, 0)
print(scores)
scores['赵云'] += 10
scores['诸葛亮'] += 100
print(scores)

# 返回None
print(scores.get('赵云2'))
# 返回指定的默认值
print(scores.get('赵云2', -1))
# 会抛异常
print(scores['赵云2'])

执行结果:

3、setdefault()方法:
以一个简单的人员按照性别分组的需求为例,说明该方法的使用:

# 人员信息的测试数据
persons = {}
for _ in range(10):
    name = fk.unique.name()
    persons[name] = {'name': name, 'age': fk.random_int(1, 150), 'gender': fk.passport_gender(),
                     'height': fk.random_int(130, 200)}

print(persons)
persons_grop_by_gender = {}
for k, v in persons.items():
    if v['gender'] in persons_grop_by_gender:
        persons_grop_by_gender[v['gender']].append(k)
    else:
        persons_grop_by_gender[v['gender']] = [k]
print(persons_grop_by_gender)

上面的代码中,我们需要进行分支判断,如果key在字典中已经存在,则将姓名追加到值的列表中,如果不存在,则首次进行初始化为值列表的操作。
逻辑没有问题,但是,有点繁琐,不太pythonic!
接下来使用setdefault()方法进行改造:

persons_grop_by_gender = {}
for k, v in persons.items():
    names = persons_grop_by_gender.setdefault(v['gender'], [])
    names.append(k)

没有了分支判断的操作,相对简洁了一些。

执行结果:

字典推导式

如同通过列表推导式构造列表对象,Python也支持通过推导式构建字典对象。

字典推到式的语法类似于列表推导式,只需要把[]换为{},单个元素,换为kk: vv形式的元素即可。
如:

dict1 = {i: i**2 for i in range(20}

还是以上面的人员信息的测试数据生成为例,这次,我们改用字典推导式来实现:

from faker import Faker
from rich import print

fk = Faker('zh_CN')

# 人员信息的测试数据
persons = {(name := fk.unique.name()): {'name': name, 'age': fk.random_int(1, 150), 'gender': fk.passport_gender(), 'height': fk.random_int(130, 200)} for _ in range(20)}

print(persons)

执行结果:



可以看到,前面通过for循环生成的测试数据,现在通过字典推导式,只需要一行代码就搞定了。


相关推荐

教你把多个视频合并成一个视频的方法

一.情况介绍当你有一个m3u8文件和一个目录,目录中有连续的视频片段,这些片段可以连成一段完整的视频。m3u8文件打开后像这样:m3u8文件,可以理解为播放列表,里面是播放视频片段的顺序。视频片段像这...

零代码编程:用kimichat合并一个文件夹下的多个文件

一个文件夹里面有很多个srt字幕文件,如何借助kimichat来自动批量合并呢?在kimichat对话框中输入提示词:你是一个Python编程专家,完成如下的编程任务:这个文件夹:D:\downloa...

Java APT_java APT 生成代码

JavaAPT(AnnotationProcessingTool)是一种在Java编译阶段处理注解的工具。APT会在编译阶段扫描源代码中的注解,并根据这些注解生成代码、资源文件或其他输出,...

Unit Runtime:一键运行 AI 生成的代码,或许将成为你的复制 + 粘贴神器

在我们构建了UnitMesh架构之后,以及对应的demo之后,便着手于实现UnitMesh架构。于是,我们就继续开始UnitRuntime,以用于直接运行AI生成的代码。PS:...

挣脱臃肿的枷锁:为什么说Vert.x是Java开发者手中的一柄利剑?

如果你是一名Java开发者,那么你的职业生涯几乎无法避开Spring。它如同一位德高望重的老国王,统治着企业级应用开发的大片疆土。SpringBoot的约定大于配置、SpringCloud的微服务...

五年后,谷歌还在全力以赴发展 Kotlin

作者|FredericLardinois译者|Sambodhi策划|Tina自2017年谷歌I/O全球开发者大会上,谷歌首次宣布将Kotlin(JetBrains开发的Ja...

kotlin和java开发哪个好,优缺点对比

Kotlin和Java都是常见的编程语言,它们有各自的优缺点。Kotlin的优点:简洁:Kotlin程序相对于Java程序更简洁,可以减少代码量。安全:Kotlin在类型系统和空值安全...

移动端架构模式全景解析:从MVC到MVVM,如何选择最佳设计方案?

掌握不同架构模式的精髓,是构建可维护、可测试且高效移动应用的关键。在移动应用开发中,选择合适的软件架构模式对项目的可维护性、可测试性和团队协作效率至关重要。随着应用复杂度的增加,一个良好的架构能够帮助...

颜值非常高的XShell替代工具Termora,不一样的使用体验!

Termora是一款面向开发者和运维人员的跨平台SSH终端与文件管理工具,支持Windows、macOS及Linux系统,通过一体化界面简化远程服务器管理流程。其核心定位是解决多平台环境下远程连接、文...

预处理的底层原理和预处理编译运行异常的解决方案

若文章对您有帮助,欢迎关注程序员小迷。助您在编程路上越走越好![Mac-10.7.1LionIntel-based]Q:预处理到底干了什么事情?A:预处理,顾名思义,预先做的处理。源代码中...

为“架构”再建个模:如何用代码描述软件架构?

在架构治理平台ArchGuard中,为了实现对架构的治理,我们需要代码+模型描述所要处理的内容和数据。所以,在ArchGuard中,我们有了代码的模型、依赖的模型、变更的模型等,剩下的两个...

深度解析:Google Gemma 3n —— 移动优先的轻量多模态大模型

2025年6月,Google正式发布了Gemma3n,这是一款能够在2GB内存环境下运行的轻量级多模态大模型。它延续了Gemma家族的开源基因,同时在架构设计上大幅优化,目标是让...

比分网开发技术栈与功能详解_比分网有哪些

一、核心功能模块一个基本的比分网通常包含以下模块:首页/总览实时比分看板:滚动展示所有正在进行的比赛,包含比分、比赛时间、红黄牌等关键信息。热门赛事/焦点战:突出显示重要的、关注度高的比赛。赛事导航...

设计模式之-生成器_一键生成设计

一、【概念定义】——“分步构建复杂对象,隐藏创建细节”生成器模式(BuilderPattern):一种“分步构建型”创建型设计模式,它将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建...

构建第一个 Kotlin Android 应用_kotlin简介

第一步:安装AndroidStudio(推荐IDE)AndroidStudio是官方推荐的Android开发集成开发环境(IDE),内置对Kotlin的完整支持。1.下载And...