Python 字典全面总结

Python 字典简介

Python 内置了字典:dict 的支持,dict 全称 dictionary,在其他语言中也称为 map,使用键-值(key-value)存储,具有极快的查找速度。

这种 key-value 存储方式,在放进去的时候,必须根据 key 算出 value 的存放位置,这样,取的时候才能根据 key 直接拿到 value。

请务必注意,dict 内部存放的顺序和 key 放入的顺序是没有关系的。

和 list 比较,dict 有以下几个特点:

  1. 查找和插入的速度极快,不会随着 key 的增加而增加;
  2. 需要占用大量的内存,内存浪费多。

而 list 相反:

  1. 查找和插入的时间随着元素的增加而增加;
  2. 占用空间小,浪费内存很少。

所以,dict 是用空间来换取时间的一种方法。字典的定义及初始化,

d = {}
d = dict()
d = {'a': 1, 'b': 2}
d = dict([('a', 1), ('b', 2)]) # 可迭代对象的元素必须是一个二元组,二元组的第0个元素为字典的key,第1个元素为字典的value
d = dict.fromkeys(range(5)) # 传入的可迭代元素为key,值为None
d = dict.fromkeys(range(5), 'abc') # 传入的可迭代元素为key,值为abc

dict 可以用在需要高速查找的很多地方,在 Python 代码中几乎无处不在,正确使用 dict 非常重要,需要牢记的第一条就是 dict 的 key 必须是不可变对象。这是因为 dict 根据 key 来计算 value 的存储位置,如果每次计算相同的 key 得到的结果不同,那 dict 内部就完全混乱了。这个通过 key 计算位置的算法称为哈希算法(Hash)。
要保证 hash 的正确性,作为 key 的对象就不能变。在Python 中,字符串、整数等都是不可变的,因此,可以放心地作为 key。而 list 是可变的,就不能作为 key:

In [1]: d = {}
In [2]: key = [1, 2, 3]
In [3]: d[key] = 'a list'
---------------------------------------------------------------------------
TypeError                                Traceback (most recent call last)
TypeError: unhashable type: 'list'

字典常用方法

首先总结一下有哪些常用的方法:

  • 增加:update
  • 删除:pop, popitem, clear
  • 修改:update
  • 查找:get
  • 其他:keys, values, items, fromkeys

字典增加或修改

update方法会修改或增加字典内容。如有下一个字典:

In [12]: dict01 = {'laven': 23, 'taoqi': 20}
In [13]: dict01
Out[13]: {'laven': 23, 'taoqi': 20}
# 使用update增加一个key-value
n [14]: dict01.update(a=123)
In [15]: dict01
Out[15]: {'a': 123, 'laven': 23, 'taoqi': 20}

当然,我们直接使用dict01['a'] = 123也是可以的,只不过我们这里介绍的是字典的update方法。接下来看看update方法的修改作用:

In [15]: dict01
Out[15]: {'a': 123, 'laven': 23, 'taoqi': 20}
In [16]: dict01.update(laven=21)
In [17]: dict01
Out[17]: {'a': 123, 'laven': 21, 'taoqi': 20}

update方法也可以接收一个二元组列表作为其参数来增加字典:

In [17]: dict01
Out[17]: {'a': 123, 'laven': 21, 'taoqi': 20}
In [18]: dict01.update([('b', 456), ('c', 789)])
In [19]: dict01
Out[19]: {'a': 123, 'b': 456, 'c': 789, 'laven': 21, 'taoqi': 20}

update的参数也可以是一个字典,不过这种形式用的比较少,还是举个例子吧:

In [20]: dict01
Out[20]: {'a': 123, 'b': 456, 'c': 789, 'laven': 21, 'taoqi': 20}
In [21]: dict01.update({'d': 987, 'e': 654})
In [22]: dict01
Out[22]: {'a': 123, 'b': 456, 'c': 789, 'd': 987, 'e': 654, 'laven': 21, 'taoqi': 20}

总结一下update的用法,它的参数的几种情况:

  • 可以是字典
  • 可以是由二元组构成的可迭代对象
  • 关键字参数

字典删除

删除字典有三种形式:

  1. pop 删除指定的key,返回该key的value
  2. popitem 随机删除,返回随机删除的一个kv二元组
  3. clear 清空字典

接下来看例子:

In [23]: dict01 = {'laven': 23, 'taoqi': 20}
# pop一个存在的key
In [24]: dict01.pop('laven')
Out[24]: 23
# pop一个不存在的key呢?
In [25]: dict01.pop('lavenliu')
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-25-a346227feeaa> in <module>()
----> 1 dict01.pop('lavenliu')
KeyError: 'lavenliu'

如果pop一个不存在的key,为了不让出现KeyError异常,我们可以为其设置一个默认值,如下:

In [26]: dict01.pop('lavenliu', 'not exist')
Out[26]: 'not exist'

接下来看看popitem方法:

In [27]: dict01
Out[27]: {'taoqi': 20}
In [28]: dict01['laven'] = 23
In [29]: dict01
Out[29]: {'laven': 23, 'taoqi': 20}
In [30]: dict01.popitem()
Out[30]: ('laven', 23) # 随机返回一个二元组
In [31]: dict01
Out[31]: {'taoqi': 20}

如果是空字典呢?我们还能否进行popitem方法呢?大家可以试试看。
最后看看字典的clear方法:

In [34]: dict01 = {'laven': 23, 'taoqi': 20}
In [35]: dict01.clear()
In [36]: dict01
Out[36]: {}

如果空字典再次执行clear方法会怎样呢?大家可以试试看。

字典查找

字典查找也可以叫做字典的访问,如果我们知道字典有哪些key,直接进行访问就可以了。如下示例:

In [38]: dict01 = {'laven': 23, 'taoqi': 20}
In [39]: dict01['taoqi']
Out[39]: 20
In [40]: dict01['laven']
Out[40]: 23

我们使用get方法试试呢?

In [41]: dict01.get('laven')
Out[41]: 23
# 访问一个不存在的key呢
In [42]: dict01.get('lavenliu')
# 发现什么都没有返回,我们可以给get方法一个默认值,
In [46]: dict01.get('lavenliu', -1)
Out[46]: -1
# 当对存在的key进行get时,返回的还是相应的value
In [47]: dict01.get('laven', -1)
Out[47]: 23

字典其他方法

字典的其他方法:

  • keys 返回所有的key
  • values 返回所有的value
  • items 返回一个二元组列表
  • fromkeys 可以批量创建字典的key-value

下面分别演示:

# keys方法演示
In [50]: dict01 = {'laven': 23, 'taoqi': 20}
In [51]: dict01.keys()
Out[51]: dict_keys(['laven', 'taoqi'])
# values方法演示
In [52]: dict01.values()
Out[52]: dict_values([23, 20])
# items方法演示
In [53]: dict01.items()
Out[53]: dict_items([('laven', 23), ('taoqi', 20)])
# fromkeys方法演示
In [54]: dict02 = {}
In [55]: dict02 = dict.fromkeys(range(5)) # 传入的可迭代元素为keys
In [56]: dict02
Out[56]: {0: None, 1: None, 2: None, 3: None, 4: None}
In [57]: dict02 = dict.fromkeys(range(5), 'not none') # 还可以给一个默认值
In [58]: dict02
Out[58]: {0: 'not none', 1: 'not none', 2: 'not none', 3: 'not none', 4: 'not none'}

字典的遍历

字典的遍历很简单:

In [48]: dict01
Out[48]: {'laven': 23, 'taoqi': 20}
In [49]: for k, v in dict01.items():...:    print(k, '=>', v)...:    
laven => 23
taoqi => 20
In [63]: for k in dict01.keys():...:    print(k, "=>", dict01[k])...:    
laven => 23
taoqi => 20

keysvaluesitems返回的都是生成器,它并不会复制一份内存。而Python2对应的方法返回的是列表,会复制一份。
还有一个不常用的方法叫做enumerate,它返回的是key的所以及相应的key。示例如下:

In [64]: for idx, k in enumerate(dict01):...:    print(idx, "=>", k)...:    
0 => laven
1 => taoqi
# 还可以这样使用
In [65]: for i, (k, v) in enumerate(dict01.items()):...:    print(i, k, "=>", v)...:    
0 laven => 23
1 taoqi => 20

根据value找其对应的key:

In [88]: d = {'a': 1, 'b': 2, 'c': 3}
In [89]: d.update(c=123)
In [90]: d
Out[90]: {'a': 1, 'b': 2, 'c': 123}
In [91]: for k, v in d.items():...:    if v == 123:...:        print(k)...:        break...:    

字典排序

由于字典是散列表,没有顺序,适合插入、查询等操作。另外字典的key不一定是字符串,但一定是不可变对象。字典排序我们使用内置的sorted函数:

In [107]: dict01
Out[107]: {'laven': 23, 'taoqi': 20}
In [108]: sorted(dict01.items(), key=lambda d: d[1], reverse=True)
Out[108]: [('laven', 23), ('taoqi', 20)]
In [109]: sorted(dict01.items(), key=lambda d: d[1], reverse=False)
Out[109]: [('taoqi', 20), ('laven', 23)]

默认字典

default初始化的时候,需要传入一个函数,这个函数也叫工厂函数。当我们使用下标访问一个key的时候,如果这个key不存在,defaultdict会自动调用初始化时传入的函数,生成一个对象作为这个key的value。一个默认字典的例子,我们来构造一个多值的字典:

In [79]: from collections import defaultdict
# 常规方法
In [80]: d = {}
In [81]: for k in range(10):...:    for v in range(10):...:        if k not in d.keys():...:            d[k] = []...:        d[k].append(v)...:        
In [82]: d
Out[82]: 
{0: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
2: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
3: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
4: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
5: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
6: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
7: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
8: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
9: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}# 使用默认字典的方法
In [83]: d = defaultdict(list)
In [84]: d
Out[84]: defaultdict(list, {})
In [85]: print(d)
defaultdict(<class 'list'>, {})
In [86]: for k in range(10):...:    for v in range(10):...:        d[k].append(v)...:        
In [87]: d
Out[87]: 
defaultdict(list,{0: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],2: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],3: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],4: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],5: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],6: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],7: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],8: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],9: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]})

有序字典

在绝大多数的编程语言中,字典都是无序的。在Python中,字典也是无序的。但标准库提供了有序字典的库,我们可以创建有序字典。但是有序字典比常规的字典要占用多一倍的内存空间。

示例如下:

In [4]: from collections import OrderedDict
In [5]: od = OrderedDict()
In [6]: od['a'] = 1
In [7]: od['b'] = 2
In [8]: od['c'] = 3
In [9]: od.keys()
Out[9]: odict_keys(['a', 'b', 'c'])
In [10]: for k, v in od.items():
...:          print(k, '->', v)
...: 
a -> 1
b -> 2
c -> 3

字典的限制

  • 字典的 key 不能重复;
  • 字典的 key 需要可 hash。

总结

今天,我们讲解了字典的绝大部分的知识点。当然了Python字典的实现这里就不讲解了,可以作为拓展内容自己进行学习了解。这里只是提一下,Python字典的实现主要有:“拉链法”和“开地址法”。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/47937.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM--自动内存管理--JAVA内存区域

1. 运行时数据区域 灰色的线程共享&#xff0c;白色的线程独享 白色的独享就是根据个体"同生共死" 程序计数器&#xff1a; 是唯一一个没有OOM(内存溢出)的地方 是线程独享的 作用&#xff1a; 是一块较小的内存空间,是当前线程所执行的字节吗的行号指示器 由于…

云监控(华为) | 实训学习day2(10)

spring boot基于框架的实现 简单应用 - 用户数据显示 开发步骤 第一步&#xff1a;文件-----》新建---项目 第二步:弹出的对话框中,左侧选择maven,右侧不选任何内容. 第三步&#xff0c;选择maven后&#xff0c;下一步 第4步 &#xff1a;出现对话框中填写项目名称 第5步&…

NSGA和MOGA 算法的异同点

NSGA&#xff08;Nondominated Sorting Genetic Algorithm&#xff09;和 MOGA&#xff08;Multi-Objective Genetic Algorithm&#xff09;都是用于多目标优化的进化算法。它们通过模拟自然选择和遗传操作来寻找优化问题的Pareto前沿&#xff0c;即在多个目标之间达到最佳折衷…

jail子系统里升级Ubuntu focal到jammy

Ubuntu focal是20.04 &#xff0c;jammy版本是22.04&#xff0c;本次的目的就是将FreeBSD jail子系统里的Ubuntu 从20.04升级到22.04 。这个focal 子系统是通过cbsd克隆得到的。使用CBSD克隆复制Ubuntu jail子系统环境-CSDN博客 do-release-upgrade升级没成功&#xff0c;用de…

(最新亲测有效)python中操作json文件追加数据

一、前言 最近想用json存储接口关联的变量数据&#xff0c;查了一下网上许多伙伴的文章&#xff0c;最后总是某个地方容易报错。最后发现还是大部分网友摘抄别人的细节问题&#xff0c;所以自己记录一下。 二、操作流程 这里我也是初学者自学&#xff0c;暂时了解到的一些内容&…

STM32 产生Hard Fault 调试方法

STM32 产生hard-fault 调试方法 当STM32 产生Hard Fault的时候可以打印出一些重要的寄存器信息&#xff0c;然后定位代码出错的地方。 https://github.com/ferenc-nemeth/arm-hard-fault-handler 下面是核心代码。 void HardFault_Handler(void) {__asm volatile("TST …

全面了解不同GPU算力型号的价格!

这两年人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&#xff09;、深度学习和高性能计算&#xff08;HPC&#xff09;领域的快速发展&#xff0c;GPU算力已成为不可或缺的资源。企业、研究机构乃至个人开发者越来越依赖于GPU加速计算来处理大规模数据集和复杂模…

如何将大模型应用到自己的业务中?7种大模型应用方式和代表论文总结

如何将大模型应用落地到自己的业务或工作中&#xff1f;这篇文章整理了7种目前业内最常用的大模型应用方法&#xff0c;以及各个方法的代表论文。通过对各种应用大模型方法的特点对比&#xff0c;找到最适合自己场景的应用方法。 1 Pretrain-Finetune 直接针对下游任务进行全…

Linux介绍和文件管理

一Linux的起源 1.Unix Dennis Ritchie和Ken Thompson发明了C语言&#xff0c;而后写出了Unix的内核 2.Minix MINIX是一种基于微 内核架构的类UNIX计算机操作系统&#xff0c;由 Andrew S. Tanenbaum发明 3.Linux内核 芬兰赫尔辛基大学的研究生Linus Torvalds基于Gcc、 ba…

分布式存储之 ceph 管理操作

一.资源池 Pool 管理 我们已经完成了 Ceph 集群的部署&#xff0c;但是我们如何向 Ceph 中存储数据呢&#xff1f;首先我们需要在 Ceph 中定义一个 Pool 资源池。Pool 是 Ceph 中存储 Object 对象抽象概念。我们可以将其理解为 Ceph 存储上划分的逻辑分区&#xff0c;Pool 由…

ELK日志收集

一、什么是ELK ELK 是由 Elasticsearch、Logstash、Kibana 三个开源软件的组成的一个组合体&#xff0c;ELK 是 elastic 公司研发的一套完整的日志收集、分析和展示的企业级解决方案。 ELK 的好处&#xff1a; ELK 组件在大数据运维系统中&#xff0c;主要可解决的问题如下&…

适用于 Android 的恢复应用程序合集分享

丢失重要文件或数据从来都不是一件有趣的事。这种情况可能发生在您的计算机和笔记本电脑上&#xff0c;也可能发生在您的 Android 智能手机或平板电脑上。然而&#xff0c;尽管 Android 用户可能认为在这种情况下他们可用的选择较少&#xff0c;但用于 Android 数据恢复的应用程…

自定义注解 + Redis 实现业务的幂等性

1.实现幂等性思路 实现幂等性有两种方式&#xff1a; ⭐ 1. 在数据库层面进行幂等性处理&#xff08;数据库添加唯一约束&#xff09;. 例如&#xff1a;新增用户幂等性处理&#xff0c;username 字段可以添加唯一约束. ⭐ 2. 在应用程序层面进行幂等性处理. 而在应用程序…

C#医学影像管理系统源码(VS2013)

目录 一、概述 二、系统功能 系统维护 工作站 三、功能介绍 影像采集 统计模块 专业阅片 采集诊断报告 报告管理 一、概述 医学影像存储与传输系统&#xff08;PACS&#xff09;是一种集成了影像存储、传输、管理和诊断功能的系统。它基于数字化成像技术、计算机技术和…

大模型+编程,未来程序员躺平还是失业?

自然语言大模型编程可以更好地理解用户的需求&#xff0c;然后输出对应代码。 最近英伟达让AI自动写代码的开源神器已上线&#xff0c;Nvidia推出了Code Llama在线体验页面&#xff0c;Code Llama 是 Llama 2 的代码专用版本&#xff0c;无需注册&#xff0c;无需本地部署&…

Jangow

关于靶场环境配置&#xff0c;确实这个靶场存在很大的问题&#xff0c;不仅仅是网络的配置问题&#xff0c;更重要的是明知道如何修改网络环境配置&#xff0c;但是键盘存在很大的问题。许多字符输入不一致。 Vulnhub靶场&#xff0c;Jangow靶机环境找不到ip解决方法。_jangow…

基于springboot新生宿舍管理系统

系统背景 在当今高等教育日益普及的时代背景下&#xff0c;高校作为知识传播与创新的重要基地&#xff0c;其基础设施的智能化管理显得尤为重要。新生宿舍作为大学生活的起点&#xff0c;不仅是学生日常生活与学习的重要场所&#xff0c;也是培养学生独立生活能力和团队合作精神…

hive动态分区导致xceivercount超限,hdfs无法创建新连接

目录 一、事件复盘&#xff1a; 二、解决方案&#xff1a; 三、讨论 一、事件复盘&#xff1a; hdfs无法创建新的文件&#xff0c;xceivercount超过最大设置&#xff0c;平时每个datanode只有100个左右的连接&#xff0c;突然达到8000以上。 事故原因&#xff0c;跨多天的…

学懂C语言(八):深入理解 register 寄存器的含义

寄存器是计算机处理器内部非常快速的一种存储设备。与普通的内存&#xff08;RAM&#xff09;相比&#xff0c;处理器访问寄存器的速度要快得多&#xff0c;因为它们位于处理器内部&#xff0c;而不是通过系统总线外部访问。这种速度优势使得寄存器非常适合用来存储那些需要频繁…

Ubuntu 24.04 LTS 桌面安装MT4或MT5 (MetaTrader)教程

运行脚本即可在 Ubuntu 24.04 LTS Noble Linux 上轻松安装 MetaTrader 5 或 4 应用程序&#xff0c;使用 WineHQ 进行外汇交易。 MetaTrader 4 (MT4) 或 MetaTrader 5 是用于交易外汇对和商品的流行平台。它支持各种外汇经纪商、内置价格分析工具以及通过专家顾问 (EA) 进行自…