Python入门【生成器推导式创建元组、字典、字典元素添加、修改、删除、序列解包、字典核心底层原理、集合 】(六)

作者简介:大家好,我是爱敲代码的小王,CSDN博客博主,Python小白
系列专栏:python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发
如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步
如果感觉博主的文章还不错的话,请三连支持一下博主哦
博主正在努力完成2023计划中:以梦为马,扬帆起航,2023追梦人

python入门到实战专栏:从入门到实战
Python爬虫开发专栏:从入门到实战
 Python办公自动化专栏:从入门到实战
Python数据分析专栏:从入门到实战
Python前后端开发专栏:从入门到实战  

目录

生成器推导式创建元组

字典

字典元素添加、修改、删除

序列解包

字典核心底层原理(重要)

集合 


 

生成器推导式创建元组

1 、从形式上看,生成器推导式与列表推导式类似,只是生成器推导式使用小括号。

2 、列表推导式直接生成列表对象,生成器推导式生成的不是列表也不是元组,而是一个生成器对象。

3、我们可以通过生成器对象,转化成列表或者元组。也可以使用生成器对象的 __next__() 方法进行遍历,或者直接作为迭代器对象来使用。不管什么方式使用,元素访问结束后,如果需要重新访问其中的元素,必须重新创建该生成器对象。

【操作】生成器的使用测试 

#列表推导式: [0, 2, 4, 6, 8]
#a = [x*2 for x in range(5)]
#print(a)
s = (x*2 for x in range(5))
print(s)   # at 0x0000021C80BE2880>
b = tuple(s)
print(b)    #(0, 2, 4, 6, 8)
c = tuple(s)
print(c)    #()
s2 = (x for x in range(3))
print(s2.__next__())        #0
print(s2.__next__())        #1
print(s2.__next__())        #2
print(s2.__next__())        #报错:StopIteration

元组总结

1 、元组的核心特点是:不可变序列。

2 、元组的访问和处理速度比列表快。

3 、与整数和字符串一样,元组可以作为字典的键,列表则永远不能作为字典的键使用。

 实时效果反馈

1. 如下代码,如下说法正确的是:

s = (x*2 for x in range(5))

A s是一个元组

B s是一个列表

C s是一个生成器对象,只能被迭代一次

D s是一个生成器对象,可以被反复迭代多次

字典

字典是“键值对”的无序可变序列,字典中的每个元素都是一个“键值 对”,包含:“键对象”和“值对象”。可以通过“键对象”实现快速获取、 删除、更新对应的“值对象”。

Python入门【生成器推导式创建元组、字典、字典元素添加、修改、删除、序列解包、字典核心底层原理、集合 】(六)_第1张图片

一个典型的字典的定义方式:

a = {'name':'gaoqi', 'age':18, 'job':'programmer'}

列表中我们通过“下标数字”找到对应的对象。字典中通过“键对象”找到对应的“值对象”。

1 “键”是任意的不可变数据,比如:整数、浮点数、字符串、元组。

2 但是:列表、字典、集合这些可变对象,不能作为“键”。

3 并且“键”不可重复。

4 “值”可以是任意的数据,并且可重复。 

字典的创建 

1 、我们可以通过{}、dict()来创建字典对象。

a = {'name':'gaoqi','age':18,'job':'programmer '}
b = dict(name='gaoqi',age=18,job='programmer')
a = dict([("name","gaoqi"),("age",18)])
c = {}  #空的字典对象
d = dict()  #空的字典对象

2、 通过zip()创建字典对象

k = ['name','age','job']
v = ['gaoqi',18,'teacher']
d = dict(zip(k,v))
print(d) #{'name': 'gaoqi', 'age': 18, 'job': 'techer'}

3 、通过fromkeys创建值为空的字典

f = dict.fromkeys(['name','age','job'])
print(f)  #结果:{'name': None, 'age': None, 'job': None}

实时效果反馈

1. 关于字典,如下说法错误的是:

A 字典是“键值对”的有序可变序列

B 字典中的“值对象”可以是任意类型

C 列表对象不可以作为字典的“键对象”

D 元组对象可以作为字典的“键对象”

字典元素的访问

为了测试各种访问方法,我们这里设定一个字典对象:

a = {'name':'gaoqi','age':18,'job':'programmer'}

1 、通过 [键] 获得“值”。若键不存在,则抛出异常。

a = {'name':'gaoqi','age':18,'job':'programmer '}
b = a['name']
print(b)

2、通过get()方法获得“值”。❤️推荐使用。优点是:指定键不存在, 返回None;也可以设定指定键不存在时默认返回的对象。推荐 使用get()获取“值对象”

a = {'name':'gaoqi','age':18,'job':'programmer '}
b = a.get('name')
c = a.get('gender', '不存在')
print(b)
print(c)

3、 列出所有的键值对

a = {'name':'gaoqi','age':18,'job':'programmer '}
b = a.items()
print(b)  #dict_items([('name', 'gaoqi'),('age', 18), ('job', 'programmer')])

4 、列出所有的键,列出所有的值

a = {'name':'gaoqi','age':18,'job':'programmer'}
k = a.keys()
v = a.values()
print(k)  #dict_keys(['name', 'age','job'])
print(v)  #dict_values(['gaoqi', 18,'programmer'])

5、 len() 键值对的个数

a = {'name':'gaoqi','age':18,'job':'programmer '}
num = len(a)
print(num)  #3

6 、检测一个“键”是否在字典中

a = {'name':'gaoqi','age':18,'job':'programmer '}
print("name" in a)  #True

实时效果反馈

1. 如下代码,如下说法正确的是:

a = {'name':'gaoqi','age':18,'job':'programmer'}
c = a.get('gender', '一个男人')

A 会报错

B 变量 c 是 None

C 变量 c 是 一个男人

D 变量 c 是 空字符串

字典元素添加、修改、删除

1、 给字典新增“键值对”。如果“键”已经存在,则覆盖旧的键值对; 如果“键”不存在,则新增“键值对”

 

a = {'name':'gaoqi','age':18,'job':'programmer '}
a['address']='西三旗1号院'
a['age']=16
print(a)
#{'name': 'gaoqi', 'age': 16, 'job': 'programmer', 'address': '西三旗1号院'}

2、 使用 update() 将新字典中所有键值对全部添加到旧字典对象上。如 果 key 有重复,则直接覆盖

a = {'name':'gaoqi','age':18,'job':'programmer '}
b = {'name':'gaoxixi','money':1000,'gender':'男的'}
a.update(b)
print(a)
#{'name': 'gaoxixi', 'age': 18, 'job': 'programmer', 'money': 1000, 'gender': '男的'}

 3 、字典中元素的删除,可以使用 del() 方法;或者 clear() 删除所有键值 对; pop() 删除指定键值对,并返回对应的“值对象”

a = {'name':'gaoqi','age':18,'job':'programmer '}
del(a['name'])
print(a)       #{'age': 18, 'job': 'programmer'}
age = a.pop('age')
print(age)     #18

4 、popitem() :随机删除和返回该键值对。字典是“无序可变序列”, 因此没有第一个元素、最后一个元素的概念; popitem 弹出随机的项,因为字典并没有"最后的元素"或者其他有关顺序的概念。若想一个接一个地移除并处理项,这个方法就非常有效(因为不用首先获取键的列表)

 

a = {'name':'gaoqi','age':18,'job':'programmer '}
r1 = a.popitem()
r2 = a.popitem()
r3 = a.popitem()
print(a)    #{}

实时效果反馈

1. 如下代码,说法正确的是:

a = {'name':'gaoqi','age':18,'job':'programmer'}
a['address']='西三旗1号院'
a['age']=16

A 字典a中会有两个age键值对: age:18, age:16

B 字典a中只有一个age: age:18

C 字典a中只有一个age: age:16

D 会报错。

序列解包

序列解包可以用于元组、列表、字典。序列解包可以让我们方便的对多个变量赋值。

x,y,z=(20,30,10)
(a,b,c)=(9,8,10)
[m,n,p]=[10,20,30]

 序列解包用于字典时,默认是对“键”进行操作; 如果需要对键值对操作,则需要使用items();如果需要对“值”进行操作,则需要使用 values();

s = {'name':'gaoqi','age':18,'job':'teacher'}
name,age,job=s #默认对键进行操作
print(name)    #name
name,age,job=s.items() #对键值对进行操作
print(name)    #('name', 'gaoqi')
name,age,job=s.values() #对值进行操作
print(name)    #gaoqi

实时效果反馈

1. 如下代码,如下说法正确的是:

s = {'name':'gaoqi','age':18,'job':'teacher'}
a,b,c=s

A 变量a的值是s

B 变量a的值是字符串"name"

C 变量a的值是字符串"gaoqi"

D 会报错

表格数据使用字典和列表存储和访问

Python入门【生成器推导式创建元组、字典、字典元素添加、修改、删除、序列解包、字典核心底层原理、集合 】(六)_第2张图片

r1 = {"name":"高小一","age":18,"salary":30000,"city":"北京"}
r2 = {"name":"高小二","age":19,"salary":20000,"city":"上海"}
r3 = {"name":"高小五","age":20,"salary":10000,"city":"深圳"}
tb = [r1,r2,r3]
#获得第二行的人的薪资
print(tb[1].get("salary"))
#打印表中所有的的薪资
for i in range(len(tb)):   # i -->0,1,2
    print(tb[i].get("salary"))
#打印表的所有数据
for i in range(len(tb)):
  print(tb[i].get("name"),tb[i].get("age"),tb[i].get("salary"),tb[i].get("city"))

 实时效果反馈

1. 如下代码,打印输出的是:

r1 = {"name":"高小一","age":18,"salary":30000,"city":"北京"}
r2 = {"name":"高小二","age":19,"salary":20000,"city":"上海"}
r3 = {"name":"高小五","age":20,"salary":10000,"city":"深圳"}
tb = [r1,r2,r3]
print(tb[2].get("city"))

A "city":"深圳"

B 上海

C 北京

D 深圳

字典核心底层原理(重要)

字典对象的核心是散列表。散列表是一个稀疏数组(总是有空白元素的数组),数组的每个单元叫做 bucket 。每个 bucket 有两部分:一 个是键对象的引用,一个是值对象的引用。

由于,所有 bucket 结构和大小一致,我们可以通过偏移量来读取指定 bucket 。

Python入门【生成器推导式创建元组、字典、字典元素添加、修改、删除、序列解包、字典核心底层原理、集合 】(六)_第3张图片

将一个键值对放进字典的底层过程

a = {}
a["name"]="xiao"

 假设字典a对象创建完后,数组长度为8:

Python入门【生成器推导式创建元组、字典、字典元素添加、修改、删除、序列解包、字典核心底层原理、集合 】(六)_第4张图片

我们要把”name”=”gaoqi”这个键值对放到字典对象a中,首先第一步需要计算键”name”的散列值。Python中可以通过hash()来计算。 

>>> bin(hash("name"))
'-0b1010111101001110110101100100101'

由于数组长度为8,我们可以拿计算出的散列值的最右边3位数字作为偏移量,即“101”,十进制是数字5。我们查看偏移量5,对应的 bucket是否为空。如果为空,则将键值对放进去。如果不为空,则 依次取右边3位作为偏移量,即“100”,十进制是数字4。再查看偏移量为4的bucket是否为空。直到找到为空的bucket将键值对放进去。流程图如下:

Python入门【生成器推导式创建元组、字典、字典元素添加、修改、删除、序列解包、字典核心底层原理、集合 】(六)_第5张图片 

Python入门【生成器推导式创建元组、字典、字典元素添加、修改、删除、序列解包、字典核心底层原理、集合 】(六)_第6张图片 

扩容

1、python会根据散列表的拥挤程度扩容。“扩容”指的是:创造更大的数组,将原有内容拷贝到新数组 中。

 2 、接近2/3时,数组就会扩容。 

根据键查找“键值对”的底层过程 

明白了,一个键值对是如何存储到数组中的,根据键对象取到值对象,理解起来就简单了。

>>> a.get("name")
'tong'

 当调用a.get(“name”),就是根据键“name”查找到“键值对”,从而找到值对象“gaoqi”。 我们仍然要首先计算“name”对象的散列值:

>>> bin(hash("name"))
'-0b1010111101001110110101100100101'

和存储的底层流程算法一致,也是依次取散列值的不同位置的数 字。 假设数组长度为8,我们可以拿计算出的散列值的最右边3位数 字作为偏移量,即 101 ,十进制是数字5。我们查看偏移量5,对应的 bucket 是否为空。如果为空,则返回 None 。如果不为空,则将这个 bucket 的键对象计算对应散列值,和我们的散列值进行比较,如果相等。则将对应“值对象”返回。如果不相等,则再依次取其他几位 数字,重新计算偏移量。依次取完后,仍然没有找到。则返回 None 。流程图如下:

 Python入门【生成器推导式创建元组、字典、字典元素添加、修改、删除、序列解包、字典核心底层原理、集合 】(六)_第7张图片

用法总结:

 1 字典在内存中开销巨大,典型的空间换时间。

2 键查询速度很快

3 往字典里面添加新键值对可能导致扩容,导致散列表中键的 次序变化。因此,不要在遍历字典的同时进行字典的修改

4 键必须可散列

      4.1 数字、字符串、元组,都是可散列的

      4.2 自定义对象需要支持下面三点:(面向对象章节中再展开说)

           4.2.1 支持 hash() 函数

          4.2.2 支持通过 __eq__() 方法检测相等性

          4.2.3 若 a==b 为真,则 hash(a)==hash(b) 也为真

集合 

Python入门【生成器推导式创建元组、字典、字典元素添加、修改、删除、序列解包、字典核心底层原理、集合 】(六)_第8张图片

集合是无序可变,元素不能重复。实际上,集合底层是字典实现, 集合的所有元素都是字典中的“键对象”,因此是不能重复的且唯一 的。 

集合创建和删除 

1、使用{}创建集合对象,并使用add()方法添加元素

a = {3,5,7}
a.add(9)    #{9, 3, 5, 7}

2、 使用set(),将列表、元组等可迭代对象转成集合。如果原来数据 存在重复数据,则只保留一个

a = ['a','b','c','b']
b = set(a)  #{'b', 'a', 'c'}

 3、 remove()删除指定元素;clear()清空整个集合

a = {10,20,30,40,50}
a.remove(20)   #{10, 50, 40,30}

集合相关操作

像数学中概念一样,Python对集合也提供了并集、交集、差集等运算。我们给出示例:

>>> a = {1,3,'sxt'}
>>> b = {'he','it','sxt'}
>>> a|b #并集
{1, 3, 'sxt', 'he', 'it'}
>>> a&b #交集
{'sxt'}
>>> a-b #差集
{1, 3}
>>> a.union(b) #并集
{1, 3, 'sxt', 'he', 'it'}
>>> a.intersection(b) #交集
{'sxt'}
>>> a.difference(b) #差集
{1, 3}

 实时效果反馈

1. 关于集合,如下说法正确的是:

A 集合是有序可变,元素不能重复

B 集合底层是字典,集合的所有元素都是字典中的“键对象”,因此 不能重复

C 集合是无序可变,元素可以重复

D 集合底层是列表

你可能感兴趣的:(python入门到实战,算法,python,开发语言,数据分析)