资讯专栏INFORMATION COLUMN

python奇遇记:数据结构窥探3

toddmark / 939人阅读

摘要:字典和集合都是基于散列表实现的,散列表也就是表,了解过数据结构的应该知道。而使用另一种办法,任何键在找不到的情况下都会用中的值数据类型比如替换。在设计时就可以使用创建你的数据接口。

这次主要说说字典和集合这两种数据类型。

字典和集合都是基于散列表实现的,散列表也就是hash表,了解过数据结构的应该知道。与散列表相关的一个概念叫做可散列,什么是可散列?在python官方定义中是这样说的:如果一个对象是可散列的,那么在这个对象的生命周期中,它的散列值是不变的,而且这个对象需要实现__hash__()方法。

python中,原子不可变类型(str、bytes和数值类型)都是可散列类型,同时所有的不可变类型也是可散列的。

集合

什么是集合?在数学中指的是具有某种特定性质的事物的总体,在python中集合指许多唯一对象的聚集。注意这个唯一,也就是说集合中不允许重复值出现,所以集合可以用来去重。

在python中,用大括号括起来表示一个集合。

data = [11, 11, 2, 3, 4, 4, 5, 4, 6]
set(data)
{2, 3, 4, 5, 6, 11}


将列表类型的data转换为集合类型后,重复值被去掉了。

在数学中,集合可以求并集、交集、差集等,python也可以做同样的事。比如:

data1 = {1, 2, 3, 4, 5}
data2 = {3, 4, 5, 6, 7}
# 交集
print(data1 & data2)
# 差集
print(data1 - data2)
# 并集
print(data1 | data2)
{3, 4, 5}
{1, 2}
{1, 2, 3, 4, 5, 6, 7}

上面说过,集合类型用大括号表示,如果我需要创建一个空集合,是不是用{ }表示就行了?问题来了,空集合用{ }表示,空字典也用{ }表示,这肯定不行。python中,创建一个空集合使用set()生成,{ }只会创建一个空的字典。

还有一个要提到的是集合推导。和列表推导、字典推导类似,这里就不讲了。

字典

字典中有几个方法需要说一下,看个例子。

a = {"x": 1, "y": 2, "z": 3}

# a.keys()返回所有键的集合,a.items()返回键值对集合,a.values返回值集合
# 可对字典进行集合运算,比较大小等运算
b = {"w" : 10,"x" : 11,"y" : 2}
# 直接进行集合操作,a.values()不可以
print(a.keys() & b.keys())
print(a.items() & b.items())
print(a.keys() - b.keys())
{"x", "y"}
{("y", 2)}
{"z"}

在字典中,可以使用a.keys()返回所有键的集合,a.items()返回键值对集合,a.values返回值集合,既然返回的是集合,就可以使用上面集合中说到的运算,大大简化操作。

在查找字典中的某个键时,如果键不存在就会报错,影响程序运行,为了避免不必要的麻烦,我们可以使用d.get(k, default),给找不到的键一个默认值。使用get的问题是,它不太符合python的哲学,d[k]比d.get(k)更加直观和简洁。

其实我们还可以这样,使用setdefault(k, default)来指定一个默认值,这个方法比get方法更高效,但是我们需要指定特殊的键。而使用另一种办法defaultdict(),任何键在找不到的情况下都会用defaultdict()中的值(数据类型比如list、str)替换。

d = {1: "a", 2: "b", 3: "c"}
d.get(4, "d")

import collections
from collections import defaultdict

d.setdefault(4, "d")
d[4]
# 如果查询5找不到,还要指定默认值

# 找不到的话用空字符串替换
d = defaultdict(str)

d[5]
""


第二个要说的是OrderedDict,它可以保持字典中的顺序,插入时是什么样就是什么样,不会改变。在设计API时就可以使用OrderDict创建你的数据接口。

怎么合并两个或者多个字典?使用ChainMap,接受字典作为参数,如果参数中某个键重复了,ChainMap会返回第一个字典中的值,这个方法也是放在collections模块下。

a = {"x": 1, "z": 3 }
b = {"y": 2, "z": 4 }

from collections import ChainMap
c = ChainMap(a,b)
print(c["x"])
print(c["y"])
# 只会返回第一个参数a中的z
print(c["z"])
1
2
3



本人才疏学浅,上文中难免有些错误,还请各位品评指正。如果觉得写的还行,欢迎关注我的公众号MLGroup,带你走进机器学习的世界。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/41049.html

相关文章

  • Python奇遇数据结构窥探2

    摘要:找出列表中小于的数据除了列表推导式,还有字典推导式,集合推导式,用法都一样。如果你的数据量很大的话,考虑使用生成器表达式。切片不仅对列表有用,同样适用于元组和字符串。切片命名使用方法,内部参数与切片一样。对剩余的的数据,使用星号代替即可。 上次我们讲了几个不常见的数据类型,每个都有自己特殊的用途,虽然不经常用到,了解一下也好。比如我们提到的数组类型,如果在数据量很大的时候同时要效率,就...

    Ocean 评论0 收藏0
  • Python奇遇数据结构窥探

    摘要:挤掉了堆中实现了堆排序。你可以用堆排序来查找一个序列中最大的或者最小的几个元素。除了使用堆排序,中还有排序和,这两个排序最终生成以列表表示的排序结果,堆排序也是。 这次我们来说说python中的数据结构。当然了,不会讲很基础的内容。 用过python的都知道,python有着与其他语言很不一样的数据类型,像什么列表、元组、集合、字典之类。这些数据类型造就了python简单易用同时又很强...

    mrli2016 评论0 收藏0
  • Python奇遇:特殊方法窥探

    摘要:在中,特殊方法以双下划线开始,以双下划线结束。真假值,如果向量模为,返回实现向量加法实现向量乘法,例如返回向量的模返回欧几里德范数找个例子运行下。怎么办中有个特殊方法,可以修改控制台输出的样式。 什么是特殊方法?当我们在设计一个类的时候,python中有一个用于初始化的方法$__init__$,类似于java中的构造器,这个就是特殊方法,也叫作魔术方法。简单来说,特殊方法可以给你设计的...

    niceforbear 评论0 收藏0
  • python奇遇:迭代器和生成器

    摘要:来说说迭代器和生成器,还有可迭代对象和生成器表达式。有点绕是不是,其实,一般只要知道可迭代对象以及它是如何实现的就行了,中常常用生成器来代替迭代器,可以说,生成器就是迭代器。 来说说迭代器和生成器,还有可迭代对象和生成器表达式。 之前简单的提到过,一个对象是可迭代的可以理解为能够使用for循环。这样说其实不太准确,某个对象可迭代是因为它内部实现了$__iter__$这个特殊方法。比如在...

    atinosun 评论0 收藏0
  • python奇遇:隐藏的python功能

    摘要:先不讲数据结构了,这次来说说中一些不被注意的功能。直接交换第二个功能。对的长度使用生成一个序列,然后遍历或者这样第三个功能。其实还接受第二个参数,它的作用是在迭代的过程中如果碰到第二个参数则停止。 先不讲数据结构了,这次来说说python中一些不被注意的功能。 在python的设计哲学中,有这么一条内容:Simple is better than complex,简单的代码比复杂的要好...

    APICloud 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<