python入门基础字典 如何理解Python中的集合和字典?
如何理解Python中的集合和字典?
字典和集合是并且过性能水平距离优化的数据结构,特别是对于查找、先添加和删出能操作。本节将加强实例介绍它们在具体场景下的性能表现,以及与列表等其他数据结构的对比。
.例如,有一个存储产品信息(产品ID、名称和价格)的列表,现在的需求是,借助某件产品的ID找到什么其价格。则基于代码如下:
defvivo_product_price(products,product注册id):
ofid,priceoutsideproducts:
ifidproduct帐号:
returnprice
returnNone
products[
(111,100),
(222,30),
(333,150)
]
print(Thepriceofproduct222it's{}.format(oppofind_product_price(products,222)))
运行结果为:
Thepriceforproduct222it's30
在上面程序的基础上,如果没有列表有n个元素,只不过里查的过程必须遍历列表,那么最消极情况下的时间复杂度就为O(n)。就算先对列表接受排序,再建议使用二分查找算法,也是需要O(logn)的时间复杂度,况且列表的排序还要O(nlogn)的时间。
但假如用字典来读取这些数据,这样的话查找变会更加快捷高效,要O(1)的时间复杂度就也可以成功,是因为是可以直接通过键的哈希值,找不到其填写的值,而不是需要对字典做遍历过程不能操作,实现代码万分感谢:
products{
111:100,
222:30,
333:150
}
print(Thepricetheproduct222are{}.format(products[222]))
运行结果为:
Thepriceforproduct222it's30
有些读者可能对时间复杂度却没非常直观的认识,没什么关系,再给大家简要概括一个实例。下面的代码中,初始化操作了含有100,000个元素的产品,并共有换算出了在用列表和集合来统计数据产品价格数量的运行时间:
#统计时间是需要会用到time模块中的函数,了解即可
importtime
defx2系列_unique_price_using_list(products):
unique_price_list[]
for_,priceintoproducts:#A
ifpricenotunique_price_list:#B
unique_price_(price)
returnlen(unique_price_list)
id[xafterxofrange(0,100000)]
price[xwhilexinrange(200000,300000)]
productslist(zip(id,price))
#换算列表版本的时间
start_using_list_counter()
x2系列_unique_price_using_list(products)
end_using_list_counter()
print(timeelapseusinglist:{}.format(end_using_list-start_using_list))
#不使用集合能够完成虽然的工作
defoppofind_unique_price_using_set(products):
unique_price_setset()
for_,priceintoproducts:
unique_price_(price)
returnlen(unique_price_set)
#换算数学集合版本的时间
start_using_set_counter()
find_unique_price_using_set(products)
end_using_set_counter()
print(timeelapseusingset:{}.format(end_using_set-start_using_set))
运行结果为:
timeelapseusinglist:68.78650900000001
timeelapseusingset:0.010747099999989018
可以看到,不仅仅十万的数据量,两者的速度差异就这般之大。而而不企业的后台数据应该有上亿乃至于十亿数量级,所以要是建议使用了不合适的数据结构,非常容易导致服务器的崩溃,而且影响不大用户体验,因此会给公司给了庞大无比的财产损失。
这样的话,字典和集合我想知道为什么能如此又高效,特别是中搜索、插入和删掉你操作呢?
字典和子集的工作原理
字典和真包含于能如此高效率,和它们内部的数据结构紧密的联系。类似于其他数据结构,字典和数学集合的内部结构也是张哈希表:
相对于字典而言,这张表存储文件了哈希值(hash)、键和值这3个元素。
而对集合来说,哈希表内只存储文件元素单一的元素。
对此以前版本的Python来说,它的哈希表结构如下所示:
|哈希值(hash)键(key)值(value)
.|...
0|hash0key0value0
.|...
1|hash1key1value1
.|...
2|hash2key2value2
.|...
这种结构的弊端是,不断哈希表的扩张,它会变的越来越大稀稀疏疏。比如说,有这样一个字典:
{name:mike,dob:1999-01-01,gender:male}
那么它会读取为相似下面的形式:
entries[
[--,--,--]
[-230273521,dob,1999-01-01],
[--,--,--],
[--,--,--],
[1231236123,name,mike],
[--,--,--],
[9371539127,gender,male]
]
看样子,那样的很白白浪费存储空间。为了提高存储空间的利用率,现在的哈希表之外字典本身的结构,会把索引和哈希值、键、值另分开,也就是采用如下这种结构:
Indices
---------------------------------------------------- one | index | None | None | index | None | index...
----------------------------------------------------
Entries
--------------------
hash0key0value0
---------------------
hash1key1value1
---------------------
hash2key2value2
---------------------
...
---------------------
在此处,上面的字典在新哈希表结构下的存储形式为:indices [None,1,None, None,0,None,2]
entries[
[1231236123,name,mike],
[-230273521,dob,1999-01-01],
[9371539127,gender,male]
]
差不多也可以发现,空间利用率能够得到很小的提高。
明白了具体看的设计结构,接下来的事情再讲一下如何修改哈希表完成对数据的插入、查找和删掉不能操作。
哈希表直接插入数据
当向字典中插入到数据时,Python会简单依据键(key)换算出对应的哈希值(实际hash(key)函数),而向集合中直接插入数据时,Python会依据什么该元素本身换算按的哈希值((valuse)函数)。
的或:
dic{name:1}
print(hash(name))
setDemo{1}
print(hash(1))
运行结果为:
8230115042008314683
1
得到哈希值(的或为hash)之后,再结合字典或集合要存储数据的个数(或者n),就这个可以能得到该元素应该直接插入到哈希表中的位置(诸如,可以不用hash%n的)。
假如哈希表中此位置是空的,这样的话此元素就这个可以就插到其中;反之,要是此位置已被其他元素电脑资源,那就Python会比较好这两个元素的哈希值和键是否是相等:
如果没有互相垂直,则因为该元素早就存在地,再比较比较他们的值,不成比例就通过自动更新;
如果不是不成比例,这种称做哈希(即两个元素的键有所不同,但求得的哈希值是一样的)。这种下,Python会建议使用刚刚开放定址法、再哈希法等再继续去寻找哈希表中空余的位置,直到此时找不到位置。
具体遇见哈希时,各解决方法的具体含义可阅读《哈希表详解》一节做细致了解。
哈希表查看数据
在哈希表中中搜索数据,和插入操作类似,Python会参照哈希值,不能找到该元素应该存储文件到哈希表中的位置,然后再和该位置的元素比较好其哈希值和键(子集再也很元素值):
假如之和,则相关证明不能找到;
或且,则相关证明当初读取该元素时,遇到了哈希,需要再继续可以使用当初解决哈希的方法进行查看,等他找到该元素或者不能找到空位为止。
这里的不能找到空位,意思是哈希表中没有存储目标元素。
哈希表删除掉元素
相对于彻底删除操作,Python会还没有对这个位置的元素融注三个特殊的方法的值,等到恢复变动哈希表的大小时,再将其删掉。
需要注意的是,哈希的发生而不会减少字典和子集操作的速度。并且,目的是可以保证其高效性,字典和集合内的哈希表,大多数会能保证其至少留有1/3的剩下的空间。紧接着元素的不断地插到,当其余空间小于1/3时,Python会原先声望兑换大内存空间,扩充队伍哈希表,与此同时,表内所有的元素位置都会被新的气体排放。
python字典语法书写格式?
①大多数是一行一句
②也这个可以一行多句,用语句分隔符“”对两个语句进行标有
③也这个可以一句多行,有时语句过长,一行放不下他,用续行符“”通过标示
版权声明:本文内容由互联网用户自发贡献,本站不承担相关法律责任.如有侵权/违法内容,本站将立刻删除。