在基础语法的学习过程里面, 列表这个类型还有字典这个类型, 是使用频率非常高的两种用来装东西的数据结构容器, 可以说, 所有的那种数据存储的任务, 不管是什么数据整理的活儿, 又或者是业务逻辑的处理工作, 基本上都会去用到这两种数据结构。
很多刚开始学习的人们, 在起步的阶段里头, 很容易把列表和字典各自适合用在什么场景给搞混掉了, 他们不太明白这两种数据结构在下面一层面上的那些差别是怎么样的, 所以当他们在对数据进行添加新数据、删除旧数据、修改数据内容、查找特定数据这些操作的时候, 就经常会遇到程序报错的问题, 或者思路变得一团乱麻, 又或者写出来的代码出现了很多重复多余的垃圾代码。
一、列表与字典的核心本质
如果想要能够非常顺手地使用这两种结构的话, 那么第一步就是要去把这两种结构它们各自在底层逻辑上的根本性定位给深刻地理解清楚。这个理解的过程就是我们所进行的每一个具体操作的基础所在。
列表这是一种有序的可变的顺序容器, 它的核心特点在于按照存入的顺序保存数据, 每一个数据都对应一个固定的数字下标, 依靠位置顺序管理数据, 列表可以存储任意类型的数据, 包括数字、字符串、布尔值, 甚至嵌套列表和字典, 适合存储一组结构统一、仅需按顺序排列的数据。
字典是一种无序的可变键值对容器, 从七点及以上版本开始, 字典会保留插入顺序, 但其本质逻辑仍然是键值映射, 不依赖下标, 字典不使用数字下标, 而是通过键和值一一对应的方式存储数据, 依靠唯一的键来管理对应的数据内容, 适合存储结构复杂、字段明确、需要通过名称精准取值的数据。
二、列表与字典的核心区别详解
实际上, 存在非常多的初学者情况是没办法完全搞清楚这两者的具体应用在什么地方的, 其主要的原因在于并不明白这两种事物在根本层面的差异性到底表现在什么地方, 因此接下来将从六个最为关键的核心维度出发进行全面的区分操作, 这样的做法主要是为了方便广大用户能够对具体的使用情况做出最为精准的判断和分析。
第一, 它们存储结构存在差异。列表采用的是线性顺序存储方式, 所有的数据都会被排列成有序队列的形式, 在这种形式下, 数据彼此之间仅仅存在位置上的关系, 而不会拥有一个专属的标识符号。
与之相对的是字典, 它使用的是键值对映射的方式来存储数据, 每一条保存的数据信息都会被拆分成独特的键以及与这个键对应的数值, 各个数据项就是靠着这些键来建立起一一对应的关系, 从而使得每条数据都具备独立的存在身份以及清晰的唯一标识。
第二, 取值的具体根据是有所区别的。列表这种结构, 它是凭借数字类型的索引下标来提取数据的,这个下标的起始位置是从0开始的, 也就是说第一个数据要对应于下标0, 而第二个数据则要对应当下标1, 这样的规律一直延续下去, 整个过程是完全依赖数据在空间上的排位来进行取值的。
字典这种结构, 它是依靠用户自定义的键来提取数据的, 它和数据本身所处的先后位置没有关系不相同, 只要你清楚具体的某个键的名称是什么, 你就能够非常准确地把跟该键相关联的值拿出来。
第三点是, 数据重复性的这些规则是不一样的。列表这个东西, 它允许把重复的数据给存进去。队列的话, 它可以存在多个完全相同的内容, 只要下标不一样, 就可以很正常地存储起来。
字典的值是可以重复的, 但是键这个是绝对不允许重复的。如果我们去定义了一个在原来就有的、同名的键, 那么后面写进去的那个键值对, 它会把前面的那个同名键值对直接给覆盖掉, 以此来保证键这一东西的唯一性。
第四个方面是适合用的地方不一样。列表, 它比较适合存那种类型相同、排成了顺序、一堆一堆的数据, 比如学生得分的那个汇总表, 或者是商品名字的那个清单, 再或者是有先后次序的任务单子, 重点就在于能批量地装东西, 然后按顺序一个一个去翻找。
字典, 它就更适合存那些乱七八糟的类型、结构很清楚的、而且有明确字段的这些数据, 比如说学生的个人资料, 里面有姓名、年龄、性别啊这些字段, 又像是商品的具体详情, 包含了价格、库存数量、生产产地啊这些内容, 主要就是为了能够快速地对上号码、准确地找到你要的那一项数值。
第五点是查询效率存在差别, 在数据规模比较小的时候, 这俩东西之间的效率差距基本上是可以被忽略掉的, 但是如果数据量变得特别大的时候, 那个差距就非常明显了, 进行列表查询操作的时候, 程序需要从头开始去遍历所有的元素, 只有找到了目标数据然后才会停止下来, 数据越多那么查询起来就会越慢, 字典它是基于哈希映射来查找数据的, 通过键可以直接定位到对应的数值, 不需要进行所谓的遍历过程, 所以它的查询效率比列表要高出很多。
第六点是有序性方面, 它们的逻辑有着非常明显的不同, 列表这个数据结构的秩序性是严格的, 存入数据的顺序和读取数据的顺序是完全一致的, 而且它可以通过下标来任意调整数据在其中的位置,反观字典它是没有所谓的下标顺序概念的, 仅仅是在新版本里面保留了插入时的顺序, 它的核心操作根本就不会依赖于顺序这种关系, 所以你没办法通过具体的数字下标去取值或者改值这一些操作。
三、列表增删改查全套操作详解
列表里面进行的所有操作, 都是围绕那些用数字来表示的下标位置以及那种有顺序的结构来展开的, 这个操作过程简单而且一看就明白, 它是对那些按顺序排列的数据进行批量处理的一个基础工作, 接下来我们会把这个添加、删除、修改和查询这几个核心逻辑一个一个地进行讲解。
1.列表新增数据
列表新增数据分为三种常用方式, 适配不同场景。第一种是尾部追加, 默认将数据添加到列表最后一位, 不影响原有数据顺序, 是最常用、最高效的新增方式, 适合批量补充数据。第二种是指定位置插入, 根据自定义下标位置, 将数据插入到列表任意位置。
插入后原有位置及后续数据自动后移, 适合需要精准调整数据顺序的场景。咱们来说说第三种办法, 这个方法的名称叫做批量合并新增, 它的具体做法呢, 就是让另一个列表里的那些全都有的数据, 统统都被添加到当前这个列表的末尾部分这样一来的话, 两个列表就能实现快速地合在一起了。
2.列表删除数据
列表删除这个操作, 它同样包含了三种核心逻辑。第一种方法叫做按下标删除, 这个方法需要我们指定那个需要被删除的数据的下标, 然后精确地把位于那个位置的元素给干掉, 等删完了以后的那些后续数据, 会自动往前移动, 把空缺的位置给补上。
第二种方法呢, 是按内容删除, 直接指定那个想要删除掉的数据到底是个什么内容, 这样就能把列表里第一个和目标数据相匹配的那个结果给删掉, 这种做法特别适合那种只知道数据内容、但是不确定下标在哪里的使用情况。不过要注意一点, 要是列表里面根本没有对应的数据存在的话, 程序就会触发一个报错机制。
第三种情况就是对列表进行清空处理, 这个操作可以通过一键删除的方式, 把列表里面所有的元素都删掉, 并且还会保留那个空列表的结构存在, 这种做法适合用在需要重复使用列表或者需要把数据重置的场景里。
除此之外, 人们还可以选择直接删除整个列表的那个变量, 这样做的目的是为了把所有的内存空间都给彻底释放出来。
3.列表修改数据
修改操作在列表中的逻辑, 可以说是最为简单的了。它核心的机制, 是依靠下标来定位目标元素。具体做法很简单。只需要你明确指出, 你想要去修改哪一个位置的元素, 也就是指定对应的下标。然后, 直接把这个下标所指向的位置, 赋上一个新的值。这样一番操作下来, 就能把原来存储在那里的数据给覆盖掉。
关于列表支持修改的这件事, 它是非常灵活的。你可以在任意的位置上进行修改, 也可以进行任意次数的修改任务。当你完成修改之后要注意, 整个列表里面的元素顺序是不会发生改变的。唯一会发生的改变就是, 那个被指定对应位置的数据本身更新了。
所以说, 这种做法其实是比较适合那种需要对有序数据进行动态更新的场景使用的。
4.列表查询数据
列表查询是分为基础查询和批量查询的。基础单点查询是通过下标取值这样的方式来实现的, 用户只需要输入指定的下标即可获取对应位置的数据, 同时它还支持负下标的查询操作, 所谓的负下标就表示从列表的末尾开始倒着取值。
另一方面, 批量查询是支持切片操作的, 借助这样的操作可以截取列表中指定区间的多个数据来生成新的子列表, 这样就能灵活地去截取部分的有序数据了。
除了上面提到这点之外, 你还能去查询那些指定好数据的下标位置到底是哪一坨, 能去统计数据一共出现了多少回, 能判定一下那个数据是不是老老实实地待在列表里头, 这样就可以满足各种各样五花八门地去查询的各种需要了。
四、字典增删改查全套操作详解
字典里面进行各种各样的动作, 都是围绕着那个唯一的键, 还有键和值之间的一对一关系才展开的, 它根本不依赖什么顺序, 也不依赖下标, 核心地方就是通过键才能够把所有的这些数据的操作都给完成了嘛, 这样子一来结构上就显得更强了, 取值的时候也就更加精准一些了。
1.字典新增数据
字典新增数据的核心逻辑, 其实就是针对一个之前不存在的键进行赋值。只要使用者去定义一个在当前字典里面根本不存在的全新键, 然后给这个新键赋予相应的数值, 那么操作就算完成了数据的增加。
经过这样处理后, 这个新的键和数据对的组合, 会自动地被放入到字典里去存放。此外, 系统也支持批量地增加数据的情形。用户可以通过使用更新方法, 让另一个完整字典中的全部键值对, 合并进入当前的字典里面。
在这个合并的过程中, 原有那些本来就不重复的数据会继续保持原样, 而那些全新的键值对则会直接作为新增的内容被加进去。这里需要予以关注的是, 键应当是类似字符串、数字以及元组这般不可变类型的存在, 万万不能采用列表、字典等可变类型来充当这个所谓的键。
2.字典删除数据
字典的删除操作, 其实全部都是基于键来实现的。 第一种方法是精准按照键来删除。 你只需要指定那个目标键就行。 这样一来, 对应的整套键值对就会一起被删掉。 也就是说, 键和值这两样东西, 会同时从这个字典里被移除掉。
第二种方法是随机删除最末尾的那个键值对。 这种操作默认是去删除这个字典里头, 最后插入进去的那一组数据。 这个方法特别适合用来批量清理位于末尾的数据项。 第三种方法则是直接清空整个字典。 这相当于只用一个简单的操作, 就把里头所有的键值对全都删干净了。
做完之后, 就只剩下一个空荡荡的字典结构放在那儿了。需要重点注意的情况是, 如果删除一个不存在的键的话, 会直接触发程序报错, 所以在日常使用之中, 可以提前进行判断, 看看这个键是否存在, 以此来避免产生程序异常的问题。
3.字典修改数据
字典修改数据这个事, 它的核心逻辑其实就是对已经存在的键重新进行赋值。虽然字典的键是不能修改的, 而且它是唯一固定的状态, 但是其对应的值却可以被随意地更新。
操作上只需要找到字典里那个已经存在的目标键, 然后给它重新赋一个值, 这时候新的数值就会直接替代掉那个原本存在的旧数值, 从而完成数据的修改工作。要是对着已存在的键多次进行重复赋值, 系统永远都会遵循后赋值的覆盖先賦值这一条规则, 这也就是字典键所具有的单一性特征的核心体现了。
同时支持批量修改这一说法, 具体而言是通过调用批量更新方法来完成的, 该方法的目的是在一次操作之中把多个已有的键的数值都给改了, 与此同时还可以去新增那些当前不存在的键值对相关的内容。
4.字典查询数据
字典查询这件事情, 分成两种情况来对待, 一种是精准取值, 另一种是批量查询。针对单点精准查询这个场景, 存在两种操作方式。第一种方式是通过键来直接进行取值, 用户只需要输入对应的键名, 系统就会返回与该键名匹配的数值内容。
这种直接查找的方法有一个明显的短处, 那就是当输入的键在字典中根本不存在的时候, 程序会抛出错误信息。第二种采用的是安全取值的处理机制, 这种机制下, 如果尝试去查询一个不存在的键, 系统不会报错。它可以依据设定, 默认返回一些为空的内容, 或者返回用户提供的一个指定提示文本。
在当前软件开发项目里面,大家更倾向于使用这种安全取值的方法来进行数据获取。批量查询功能支持单独获取字典里面所有的键、所有的值,还有所有的键值对。用户可以通过遍历的方式来对字典数据进行大批量的处理。这个功能同时还支持去判断某一个指定的键, 是不是真的存在于这字典里面。
这样做主要是为了给后面的数据查询操作、数据修改操作、数据删除操作提供事前的判断条件。
五、列表与字典选用核心口诀
新手如果想快速地选出一个适合自己的数据结构的话, 可以总结一些简单又实用的选择规则, 如果有有序的数据、并且同类数据、还有只看顺序的情况的话就用列表, 结构很复杂、字段明确、精准取值的话就用字典, 说得更直白一点就是存一串数据的时候选列表, 存一条完整的多维度信息的时候选字典, 在实际进行开发的时候这两种东西经常会嵌套着用, 比如列表里面套字典这种形式, 用这种方式来存储多条结构化数据, 这样就能兼顾批量存储和精准取值的优势。