如何理解python中的集合和字典?
字典和集合是高度优化的数据结构,特别是对于查找、添加和删除操作。本节将通过示例介绍它们在特定场景中的性能,并将它们与列表等其他数据结构进行比较。
例如,有一个存储产品信息(产品id、名称和价格)的列表,现在的需求是借助产品id找出价格。实现代码如下:
定义查找_产品_价格(产品,product_id):
对于id,products:的价格
如果我是product_id:
退货价格
不返回
产品[
(111,100),
(222,30),
(333,150)
]
打印(产品222的价格是{}。格式(find_product_price(products,222)))
运行结果如下:
产品222的价格是30英镑
在上述方案的基础上,如果链表有n个元素,由于搜索过程需要遍历链表,那么最坏情况下的时间复杂度为o(n)。即使先对列表进行排序,再使用二分搜索法算法,也要o(logn)时间复杂度,更不用说o(nlogn)时间对列表进行排序了。
但是如果用字典来存储这些数据,那么查找会非常方便高效,而且可以用o(1)的时间复杂度来完成,因为不需要遍历字典,直接通过键的哈希值就可以找到对应的值。实现代码如下:
产品{
111:100,
222:30,
333:150
}
打印(产品222的价格是{}。格式(产品[222])
运行结果如下:
产品222的价格是30英镑
有些读者可能对时间复杂性没有直观的理解。它不没关系。我再给你举个例子。在下面的代码中,初始化100,000个元素的产品,分别计算使用list和set统计产品价格数量的运行时间:
#统计时间需要使用时间模块中的函数,就知道了。
导入时间
deffind_unique_price_using_list(products):
唯一价格列表[]
对于_,products:的价格#a
如果价格不在unique_pric:#b
唯一价格(价格)
returnlen(唯一价格列表)
id[范围(0,100000)中x的x]
价格[x对x,在范围(200000,300000)内]
产品列表(邮政编码(id,价格))
#计算列表版本的时间
start_using_list_counter()
查找_唯一_价格_使用_列表(产品)
end_using_list_count:{}打印(经过的时间)。格式(结束使用列表开始使用列表)
#使用集合做同样的工作
deffind_unique_price_using_set(products):
unique_price_set集合()
对于_,products:的价格
唯一价格(价格)
returnlen(唯一价格集)
#计算集合版本的时间
启动使用设置计数器()
查找_唯一_价格_使用_集合(产品)
end_using_set_count:{}打印(经过的时间)。格式(结束使用设置-开始使用设置)
运行结果如下:
使用list:68的时间流逝。56866.66666666667
使用s:0.01表示时间流逝。58660.08888888861
能看到了吧,才十万个数据,两者的速度差那么大。而企业的后台数据往往是几亿甚至几十亿的量级。因此,如果使用不合适的数据结构,很容易导致服务器崩溃,不仅影响用户体验,还会给公司带来巨大的财产损失。
那么,为什么字典和收藏的效率如此之高,尤其是查找、插入和删除的操作?
字典和收藏的工作原理。
字典和集合的效率与其内部数据结构密切相关。与其他数据结构不同,字典和集合的内部结构是哈希表:
对于字典来说,这个表存储三个元素:散列、键和值。
对于集合,哈希表中只存储一个元素。
对于以前版本的python,其哈希表结构如下:
|哈希值(哈希)键值(值)
。|...
0|哈希0键0值0
。|...
1|hash1k:·迈克,dob:1999-01-01,g:男}
然后,它将以类似于下面的形式存储:
条目[
[-,-,-]
[-230273521,出生日期,1999年1月1日],
[-,-,-],
[-,-,-],
[1231236123,姓名,迈克],
[-,-,-],
[9371539127,性别,男]
]
显然,这是对存储空间的极大浪费。为了提高存储空间的利用率,目前的哈希表除了字典本身的结构之外,还会将索引与哈希值、键和值分开,就是下面这种结构:
指数
-
无|索引|无|无|索引|无|索引...
-
进入
-
哈希0键0值0
--
hash1key1值1
-
hash2键2值2
-
...
-
在此基础上,上述字典在新哈希表结构下的存储形式为:
索引[无,1,无,无,0,无,2]
条目[
[1231236123,姓名,迈克],
[-230273521,出生日期,1999年1月1日],
[9371539127,性别,男]
]
通过对比可以发现,空间利用率有了很大的提高。
明确具体的设计结构,然后分析如何使用哈希表完成数据的插入、查找和删除。
哈希表插入数据
在向字典中插入数据时,python会先根据键(通过hash(key)函数)计算出相应的哈希值,而在向集合中插入数据时,python会根据元素本身(通过hash(value)函数)计算出相应的哈希值。
例如:
dic{nam:1}
打印(哈希(名称))
s《哈希表详解》一节中详细了解。
哈希表查找数据
在哈希表中查找数据类似于插入操作。python会根据哈希值找到元素在哈希表中应该存放的位置,然后将其哈希值和k
pythonlist占用多大内存?
列表类似于向量。
对象和指针数组是分开分配的,数组在堆上。指针数组的大小是动态分配的,分配的内存必须大于实际的。由于是动态分配的,realloc在调整大小时会移动数据和复制数据。对于大量数据最好使用链表。
字典类似于散列表
默认情况下,字典本身是有元素容量的,如果不足,会在堆上分配。如果需要扩展或收缩,内存将被动态地重新分配并再次散列。dictkeys()和其他调用生成一个列表。如果数量很大,建议使用迭代器。
原文标题:python 两个list对比 如何理解Python中的集合和字典?,如若转载,请注明出处:https://www.shcrbfchs.com/tag/9839.html
免责声明:此资讯系转载自合作媒体或互联网其它网站,「泰福润金」登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,文章内容仅供参考。