Python 核心技术与实战 --02 字典和集合

什么是字典?
字典是一系列由键(key) 和 值(value) 配对组成的元素集合,在python3.7+ , 字典被确定为有序(注意在3.6 中,字典有序是一个implementation detail, 在3.7 才正式成为语言特性),而在3.6 无法100% 保证有序性,而在3.6 之前是无序的,其长度大小可变,元素可以任意地删减和改变。

相比于列表和元组,字典的性能更优,特别是相对于查找/添加/删除的操作,字典都能在常数时间复杂度内完成。

而集合和字典基本相同,唯一的区别,就是集合没有键和值的配对,是一系列无序的/唯一的元素组合。

首先我们来看字典和集合的创建,通常有以下几种方式

d1={‘name‘:‘jason‘,‘age‘:20}

d2=dict({‘name‘:‘jason‘,‘age‘:20})

d3=dict([(‘name‘,‘jason‘),(‘age‘,20)])

d4=dict(name=‘jason‘,age=20)

s1={1,2,3}

s2=set([1,2,3])

python 中字典和集合,无论是键还是值,都可以是混合类型。比如下面这个例子,我创建了一个元素为1,’hello‘,5.0 的集合

元素访问问题。字典访问可以直接索引键,如果不存在就抛出异常。

d ={‘name‘:jason‘,‘age‘:20}
d.get(‘name‘)
d.get(‘location‘,‘null‘)
如果不存在就返回 ‘null‘ 默认值

集合

集合本质上是一个哈希表,和列表不一样。所以集合不支持索引操作。

想要判断一个元素在不在字典或集合内,我们可以用value in dict/set 来判断。

s={1,2,3}
1 in s
True

10 in s
False

d = {‘name‘:‘jason‘,‘age‘:20}
‘name‘ in d
True

‘location‘ in d
False

增加/删除/更新操作

d={‘name‘:‘jason‘,‘age‘:20}
d[‘gender‘]=‘male‘
d[‘dob‘]=‘1999-02-01‘
d.pop(‘dob‘)

s={1,2,3}
s.add(4)
s.remove(4)

集合的pop() 操作是删除集合中最后一个元素,可是集合本身是无序的所以你无法知道会删除哪个元素,这个操作谨慎使用


实际应用中,很多情况下,我们需要对字典或集合进行排序,比如,取出值最大的50对。

对于字典,我们通常会根据键或者值,进行升序或降序排序:

d={"a‘:1,‘c‘:3,‘d‘:4}
sorted_by_key = sorted(d.items(),key=lambda x:x[0])
sorted_by_value = sorted(d.items(),key=lambda x:x[1])

字典和集合的性能

字典和集合是进行过高度性能优化的数据结构,特别是对于查找/添加/和删除操作。那接下来,我们就来看看,它们在具体的场景下的性能表现,以及与列表等其他数据结构进行对比

比如某电商企业的后台,存储了每件产品的ID/名称/和价格。现在的需求是,给定某件商品的ID,我们要求找出其价格

如果我们用列表来存储这些数据结构,并进行查找,相应代码如下

def find_product_price(products,product_id):
      for id,price in products:
             if id == product_id:
                   return price
       return None

products=[(143121312,100),
                (23121312,30),
                 (32421312,150)]

假设列表中有n个元素,而查找的过程要遍历列表,那么时间复杂度为O(n). 即使我们先对列表进行排序,然后再使用二分查找,我们也需要O(logn) 的时间复杂度,更何况,列表的排序还需要O(nlogn)的时间。

但如果使用字典来存储这些数据,那么查找就会非常便捷高效,只需要O(1) 的时间复杂度就可以完成。原因很简单,刚刚提到过的,字典的内部组成是一张哈希表,你可以直接通过键的哈希值,找到其对应的值。

类似的,现在需求变成,要找出这些商品有多少种不同的价格。我们还用同样的方法来比较一下。

如果还是选择用列表,对应的代码如下,其中,A和B是两层循环。同样假设原始列表有n个元素,那么最差的情况下,需要O(n^2)的时间复杂度。

def find_unique_price_using_list(products):
      unique_price_list =[]
      for _,price in products:
          if price not in unique_price_list:
                  unique_price_list.append(price)
      return len(unique_price_list)

但如果我们选择使用集合这个数据结构,由于集合是高度优化的哈希表,里面的元素不能重复,并且其添加和查找操作只需要O(1)的复杂度,那么,总的时间复杂度就只是O(n)

def find_unique_price_using_set(products):
      unique_price_set =set()
      for _,price in products:
                  unique_price_set.add(price)
      return len(unique_price_set)

字典和集合的工作原理:

字典集合内部的数据结构都是一张哈希表。

对于字典而言,这张表存储了哈希值(hash)/键/值这三个元素。

而对于集合来说,区别就是哈希表内没有键值的配对,只有单一的元素。

老版本的哈希表结构:

哈希值(hash)     键(key)          值(value)
---------------------------------------------
hash0                key0             value0
---------------------------------------------
hash1                key1             value1
---------------------------------------------
hash2                key2             value2
-------------------------------------------

不难想象,随着哈希表的扩张,它会变得越来越稀疏。举个例子,比如我有这样一个字典:

{‘name‘:‘mike‘,‘dob‘:‘1991-01-01‘,‘‘gender‘:‘male‘}

那么它会存储为类似下面的形式:

entries=[
[‘--‘,‘--‘,‘--‘],
[-230273521,‘dob‘,‘1999-01-01‘],
[‘--‘,‘--‘,‘--‘],
[‘--‘,‘--‘,‘--‘],
[‘1231236123‘,‘name‘,‘mike‘],
[‘--‘,‘--‘,‘--‘],
[9371539127‘,‘gender‘,‘male‘]
]

这样的设计结构非常浪费存储空间。为了提高内存的利用率,现在的哈希表除了字典本身的结构,会把索引和哈希值/键/值单独分开,也就是下面的这样新的结构

Indices
--------------------------------------------------------------------------
None| index| None| None| index|None|index|....
-------------------------------------------------------------------------

Entries
--------------------
hash0 key0 value0
-----------------------
hash1  key1  value1
------------------------
hash2   key2   value2


原文地址:https://www.cnblogs.com/qifei-liu/p/12090331.html

时间: 2024-09-30 07:43:51

Python 核心技术与实战 --02 字典和集合的相关文章

Python核心技术与实战

课程目录:第00课.开篇词丨从工程的角度深入理解Python.rar第01课.如何逐步突破,成为Python高手?.rar第02课.Jupyter Notebook为什么是现代Python的必学技术?.rar第03课.列表和元组,到底用哪一个?.rar第04课.字典.集合,你真的了解吗?.rar第05课.深入浅出字符串.rar第06课.Python “黑箱”:输入与输出.rar第07课.修炼基本功:条件与循环.rar第08课.异常处理:如何提高程序的稳定性?.rar第09课.不可或缺的自定义函数

Python 元组、列表、字典和集合

元组 Python中的元组(Tuple)类似于Java中的数组,一旦创建了一个 tuple,就不能以任何方式改变它.这点与Python中的字符串类似,所以我们说元组和字符串都是不可变的序列.元组也支持索引和分片操作. 定义一个元组使用一对小(圆)括号" ( ) ". #定义一个元组 tuple1 = (1, 2, '3', 4, '5') # 定义了一个元组之后就无法再添加或修改元组中的元素 print tuple1[0] # 元组的元素都有确定的顺序.元组的索引也是以0为基点的 pr

Python基础2 列表、字典、集合

本节内容 列表.元组操作 字符串操作 字典操作 集合操作 文件操作 字符编码与转码 1. 列表.元组操作 列表是我们最以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作 定义列表 names = ['Alex',"Tenglan",'Eric'] 通过下标访问列表中的元素,下标从0开始计数 >>> names[0] 'Alex' >>> names[2] 'Eric' >>> names[-1] 'Eric'

python基础10 字符串操作,字典操作,集合操作

本节内容: 字符串操作 字典操作 集合操作 字符串操作 概述 字符串是以''或""括起来的任意文本,比如'abc',"xyz"等等.请注意,''或""本身只是一种表示方式,不是字符串的一部分,因此,字符串'abc'只有a,b,c这3个字符. 如果字符串本身包含'怎么办?比如我们要表示字符串 I'm OK ,这时,可以用" "括起来表示: "I'm OK" 类似的,如果字符串包含",我们就可以用'

python列表,元组,字典,集合的比较总结

这四个都是python中的序列,用于存放数据,他们区别总结如下:   列表list 元组tuple 字典dictionary 集合set 是否可变 可变 不可变 可变 可变 是否有序 有序 有序 无序 无序 元素是否重复 可重复 可重复 键不可重复 不可重复 定义符号 [] () {key:value} {} 创建 1.[]直接创建 2.list() 3.列表生成式 1.()直接创建 2.tuple() 1.{}直接创建 2.dict(key1=value1) 3.dict(zip(list1,

Python核心技术与实战——十三|Python中参数传递机制

我们在前面的章节里学习了Python的函数基础以及应用,那么现在想一想:传参,也就是把一些参数从一个函数传递到另一个函数,从而使其执行相应的任务,这个过程的底层是如何工作的,原理又是怎样的呢? 在实际过程中,我们写完了代码测试时候发现结果和预期值不一样,在一次次debug后发现是传参过程中数据结构发生了改变,导致程序出错.比富我们把一个列表作为实参传递给另一个函数,但是我们并不希望列表再函数运行结束后发生变化.但往往事与愿违,由于某些额外的操作改变了他的值,那就导致后续程序一系列错误的发生.因此

第七节:python列表、元组、字典、集合

python个人笔记,纯属方便查询: ################################## ################################## ################################## i=['car','clothes','ipone']      #语法 i         #查看所有的元素 i[0]     #取第一个 i[1]     #取第二个 i[-1]    #取最后一个  i[0:10]   #取一个到第九个  i[-

python基础之列表,字典,集合

1,列表 (1) L1 =  [  ] # 创建空列表                    #需要注意的是,python和其他语言例如Java不一样,定义的时候不需要声明数据类型.具体原因是                        不用声明变量一样,Python不用去声明函数的返回类型,是由于其"若类型"的语言特性决定的.                        在其他语言中,例如C/C++语言中在存储一个数据之前,都需要在内存中给这个数据开辟一个固定的内存空间,   

Python 列表、元组、字典及集合操作详解

转自:https://www.cnblogs.com/Jimc/p/9584606.html 一.列表 列表是Python中最基本的数据结构,是最常用的Python数据类型,列表的数据项不需要具有相同的类型 列表是一种有序的集合,可以随时添加和删除其中的元素 列表的索引从0开始 1.创建列表 >>> list1 = ['python', 2018, 'python3', 1994] >>> list1 ['python', 2018, 'python3', 1994]