Python学习篇6-序列(列表、元组、字典、集合)

如果对您有一丁点的帮助,劳烦动动手指点个赞,您的支持和鼓励是搬砖人不断创作的动力!

序列

序列是一种数据存储方式,用来存储一系列的数据。在内存中,序列就是一块用来存放多个值的连续的内存空间。比如一个整数序列[ 10 , 20 , 30 , 40 ],可以这样示意表示:

由于Python 3 中一切皆对象,在内存中实际是按照如下方式存储的:a=[ 10 , 20 , 30 , 40 ]

从图示中,我们可以看出序列中存储的是整数对象的地址,而不是整数对象的值。python中常用的序列结构有:字符串、列表、元组、字典、集合。

我们上一章学习的字符串就是一种序列。关于字符串里面很多操作,在这一章中仍然会用到,大家一定会感觉非常熟悉。

本章内容,我们必须非常熟悉。无论是在学习还是工作中,序列都是每天都会用到的技术,可以非常方便的帮助我们进行数据存储的操作。

1.列表简介

列表:用于存储任意数目、任意类型的数据集合。

列表是内置可变序列,是包含多个元素的有序连续的内存空间。列表定义的标准语法格式:

a=[ 10 , 20 , 30 , 40 ]
其中, 10 , 20 , 30 , 40 这些称为:列表a的元素。
列表中的元素可以各不相同,可以是任意类型。比如:
a=[ 10 , 20 ,‘abc’,True]
列表对象的常用方法汇总如下,方便大家学习和查阅。

方法要点 描述
list.append(x)增加元素将元素X增加到列表list尾部
list.extend(aList)增加元素将列表alist所有元素加到列表list尾部
list.insert(index,x)增加元素在列表list指定位置index处插入元素x
list.remove(x)删除元素在列表list中删除首次出现的指定元素x
list.pop([index])删除元素删除并返回列表list指定为止index处的兀素,默认是 最后一个元素
list.clear()删除所有兀素删除列表所有元素,并不是删除列表对象
list.index(x)访问元素返回第一个X的索引位置若不存在X兀素抛出异常
list.cou nt(x)计数返回指定元素X在列表list中出现的次数
len(list)列表长度返回列表中包含兀素的个数
list.reverse()翻转列表所有元素原地翻转
list.sortO排序所有元素原地排序
list.copyO浅拷贝返回列表对象的浅拷贝

Python的列表大小可变,根据需要随时增加或缩小。

字符串和列表都是序列类型,一个字符串是一个字符序列,一个列表是任何元素的序列。我们前面学习的很多字符串的方法,在列表中也有类似的用法,几乎一模一样。

2.列表的创建

基本语法[]创建
>>>a=[ 10 , 20 ,'gaoqi','sxt']
>>>a=[] #创建一个空的列表对象
list()创建

使用list()可以将任何可迭代的数据转化成列表。

>>>a=list() #创建一个空的列表对象
>>>a=list(range( 10 ))
>>>a
>>>[ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]
>>>a=list("gaoqi,sxt")
>>>a
>>>['g','a','o','q','i',',','s','x','t']
range()创建整数列表

range()可以帮助我们非常方便的创建整数列表,这在开发中及其有用。语法格式为:
range([start,]end[,step])
start参数:可选,表示起始数字。默认是 0
end参数:必选,表示结尾数字。
step参数:可选,表示步长,默认为 1
python 3 中range()返回的是一个range对象,而不是列表。我们需要通过list()方法将其
转换成列表对象。
典型示例如下:

>>>list(range( 3 , 15 , 2 ))
>>>[ 3 , 5 , 7 , 9 , 11 , 13 ]
>>>list(range( 15 , 3 ,- 1 ))
>>>[ 15 , 14 , 13 , 12 , 11 , 10 , 9 , 8 , 7 , 6 , 5 , 4 ]
>>>list(range( 3 ,- 10 ,- 1 ))
[ 3 , 2 , 1 , 0 ,- 1 ,- 2 ,- 3 ,- 4 ,- 5 ,- 6 ,- 7 ,- 8 ,- 9 ]
推导式生成列表(简介一下,重点在for循环后讲)

使用列表推导式可以非常方便的创建列表,在开发中经常使用。但是,由于涉及到for循环和if语句。在此,仅做基本介绍。在我们控制语句后面,会详细讲解更多列表推导式的细
节。

>>>a=[x* 2 for x inrange( 5 )] #循环创建多个元素
>>>a
>>>[ 0 , 2 , 4 , 6 , 8 ]
>>>a=[x* 2 forxinrange( 100 )ifx% 9 == 0 ] #通过if过滤元素
>>>a
>>>[ 0 , 18 , 36 , 54 , 72 , 90 , 108 , 126 , 144 , 162 , 180 , 198 ]

3.列表元素的增加和删除

当列表增加和删除元素时,列表会自动进行内存管理,大大减少了程序员的负担。但这个特点涉及列表元素的大量移动,效率较低。除非必要,我们一般只在列表的尾部添加元素或删除元素,这会大大提高列表的操作效率。

append()方法

原地修改列表对象,是真正的列表尾部添加新的元素,速度最快,推荐使用。

>>>a=[ 20 , 40 ]
>>>a.append( 80 )
>>>a
[ 20 , 40 , 80 ]
+运算符操作

并不是真正的尾部添加元素,而是创建新的列表对象;将原列表的元素和新列表的元素依次复制到新的列表对象中。这样,会涉及大量的复制操作,对于操作大量元素不建议使用。

>>>a=[ 20 , 40 ]
>>>id(a)
>>>46016072
>>>a=a+[ 50 ]
>>>id(a)
>>>46015432

通过如上测试,我们发现变量a的地址发生了变化。也就是创建了新的列表对象。

extend()方法

将目标列表的所有元素添加到本列表的尾部,属于原地操作,不创建新的列表对象。

>>>a=[ 20 , 40 ]
>>>id(a)
>>>46016072
>>>a.extend([ 50 , 60 ])
>>>id(a)
>>>46016072
insert()插入元素

使用insert()方法可以将指定的元素插入到列表对象的任意制定位置。这样会让插入位置后面所有的元素进行移动,会影响处理速度。涉及大量元素时,尽量避免使用。类似发生这种移动的函数还有:remove()、pop()、del(),它们在删除非尾部元素时也会发生操作位置后面元素的移动。

>>>a=[ 10 , 20 , 30 ]
>>>a.insert( 2 , 100 )
>>>a
>>>[ 10 , 20 , 100 , 30 ]
乘法扩展

使用乘法扩展列表,生成一个新列表,新列表元素时原列表元素的多次重复。

>>>a=['sxt', 100 ]
>>>b=a* 3
>>>a
>>>['sxt', 100 ]
>>>b
>>>['sxt', 100 ,'sxt', 100 ,'sxt', 100 ]

适用于乘法操作的,还有:字符串、元组。例如:

>>>c='sxt'
>>>d=c* 3
>>>c
>>>'sxt'
>>>d
>>>'sxtsxtsxt'

4.列表元素的删除

del删除

删除列表指定位置的元素。

>>>a=[ 100 , 200 , 888 , 300 , 400 ]
>>>dela[ 1 ]
>>>a
>>>[ 100 , 200 , 300 , 400 ]

在这里插入图片描述

5.pop()方法

pop()删除并返回指定位置元素,如果未指定位置则默认操作列表最后一个元素。

>>>a=[ 10 , 20 , 30 , 40 , 50 ]
>>>a.pop()
50
>>>a
>>>[ 10 , 20 , 30 , 40 ]
>>>a.pop( 1 )
>>>20
>>>a
>>>[ 10 , 30 , 40 ]
remove()方法

删除首次出现的指定元素,若不存在该元素抛出异常。

>>>a=[ 10 , 20 , 30 , 40 , 50 , 20 , 30 , 20 , 30 ]
>>>a.remove( 20 )
>>>a
>>>[ 10 , 30 , 40 , 50 , 20 , 30 , 20 , 30 ]
>>>a.remove( 100 )
>>>Traceback(mostrecentcalllast):
>>>File"<pyshell# 208 >",line 1 ,in<module>
>>>a.remove( 100 )
>>>ValueError:list.remove(x):xnotinlist

6.列表元素访问和计数

通过索引直接访问元素

我们可以通过索引直接访问元素。索引的区间在[ 0 ,列表长度- 1 ]这个范围。超过这个范围则会抛出异常。

>>>a=[ 10 , 20 , 30 , 40 , 50 , 20 , 30 , 20 , 30 ]
>>>a[ 2 ]
>>>30
>>>a[ 10 ]
>>>Traceback(mostrecentcalllast):
>>>File"<pyshell# 211 >",line 1 ,in<module>
>>>a[ 10 ]

IndexError:listindexoutofrange

index()获得指定元素在列表中首次出现的索引

index()可以获取指定元素首次出现的索引位置。语法是:index(value,[start,[end]])。其中,
start和end指定了搜索的范围。

>>>a=[ 10 , 20 , 30 , 40 , 50 , 20 , 30 , 20 , 30 ]
>>>a.index( 20 )
>>>1
>>>a.index( 20 , 3 )
>>>5
>>>a.index( 20 , 3 ) #从索引位置 3 开始往后搜索的第一个 20
>>>5
>>>a.index( 30 , 5 , 7 ) #从索引位置 5 到 7 这个区间,第一次出现 30 元素的位置
>>>6
count()获得指定元素在列表中出现的次数

count()可以返回指定元素在列表中出现的次数。

>>>a=[ 10 , 20 , 30 , 40 , 50 , 20 , 30 , 20 , 30 ]
>>>a.count( 20 )
>>>3
len()返回列表长度

len()返回列表长度,即列表中包含元素的个数。

>>>a=[ 10 , 20 , 30 ]
>>>len(a)
>>>3
成员资格判断

判断列表中是否存在指定的元素,我们可以使用count()方法,返回 0 则表示不存在,返回大于 0 则表示存在。但是,一般我们会使用更加简洁的in关键字来判断,直接返回True或False。

>>>a=[ 10 , 20 , 30 , 40 , 50 , 20 , 30 , 20 , 30 ]
>>>20 ina
>>>True
>>>100 notina
>>>True
>>>30 notina
>>>False

7.切片操作

我们在前面学习字符串时,学习过字符串的切片操作,对于列表的切片操作和字符串类似。
切片是Python序列及其重要的操作,适用于列表、元组、字符串等等。切片的格式如下:
切片slice操作可以让我们快速提取子列表或修改。标准格式为:
[起始偏移量start:终止偏移量end[:步长step]]

注:当步长省略时顺便可以省略第二个冒号

典型操作(三个量为正数的情况)如下:

操作和说明示例结果
[:] 提取整个列表[10,20,30][:][10,20,30]
[start:]从start索引开始到 结尾[10,20,30] [1:][20,30]
[:end]从头开始知道end-1[10,20,30] [:2][10,20]
[start:end]从 start 至 1」en d-1[10,20,30,40][1:3][20,30]
[start: end:step]从 start 提 取到end-1 ,步长是step[10,20,30,40,50,6070] [1:6: 2][20, 40, 60]

其他操作(三个量为负数)的情况:

示例说明结果
[10,20,30,40,50,60,70][-3:]倒数三个[50,60,70]
[10, 20, 30, 40, 50, 60,70][-5:-3]倒数第五个到倒数第三个(包头不包尾)[30,40]
[10,20,30,40,50,60,70][::-1]步长为负,从右到左,反向提取[70, 60, 50, 40, 30, 20, 10]

切片操作时,起始偏移量和终止偏移量不在[ 0 ,字符串长度- 1 ]这个范围,也不会报错。起始

偏移量小于 0 则会当做 0 ,终止偏移量大于“长度- 1 ”会被当成”长度- 1 ”。例如:

>>>[ 10 , 20 , 30 , 40 ][ 1 : 30 ]
[ 20 , 30 , 40 ]

我们发现正常输出了结果,没有报错。

列表的遍历

for obj in listObj:
	print(obj)

8.复制列表所有的元素到新列表对象

如下代码实现列表元素的复制了吗?

list 1 =[ 30 , 40 , 50 ]
list 2 =list 1
只是将list 2 也指向了列表对象,也就是说list 2 和list 2 持有地址值是相同的,列表对象本身的元素并没有复制。

我们可以通过如下简单方式,实现列表元素内容的复制:
list 1 =[ 30 , 40 , 50 ]
list 2 =[]+list 1

注:我们后面也会学习copy模块,使用浅复制或深复制实现我们的复制操作。

9.列表排序

修改原列表,不建新列表的排序
>>>a=[ 20 , 10 , 30 , 40 ]
>>>id(a)
>>>46017416
>>>a.sort() #默认是升序排列
>>>a
>>>[ 10 , 20 , 30 , 40 ]
>>>a=[ 10 , 20 , 30 , 40 ]
>>>a.sort(reverse=True) #降序排列
>>>a
>>>[ 40 , 30 , 20 , 10 ]
>>>importrandom
>>>random.shuffle(a) #打乱顺序
>>>a
>>>[ 20 , 40 , 30 , 10 ]
建新列表的排序

我们也可以通过内置函数sorted()进行排序,这个方法返回新列表,不对原列表做修改。

>>>a=[ 20 , 10 , 30 , 40 ]
>>>id(a)
>>>46016008
>>>a=sorted(a) #默认升序
>>>a
>>>[ 10 , 20 , 30 , 40 ]
>>>id(a)
>>>45907848
>>>a=[ 20 , 10 , 30 , 40 ]
>>>id(a)
>>>45840584
>>>b=sorted(a)


>>>b
>>>[ 10 , 20 , 30 , 40 ]
>>>id(a)
>>>45840584
>>>id(b)
>>>46016072
>>>c=sorted(a,reverse=True) #降序
>>>c
>>>[ 40 , 30 , 20 , 10 ]

通过上面操作,我们可以看出,生成的列表对象b和c都是完全新的列表对象。

reversed()返回迭代器

内置函数reversed()也支持进行逆序排列,与列表对象reverse()方法不同的是,内置函数
reversed()不对原列表做任何修改,只是返回一个逆序排列的迭代器对象。

>>>a=[ 20 , 10 , 30 , 40 ]
>>>c=reversed(a)
>>>c
>>><list_reverseiteratorobjectat 0 x 0000000002 BCCEB 8 >
>>>list(c)
>>>[ 40 , 30 , 10 , 20 ]
>>>list(c)
>>>[]

我们打印输出c发现提示是:list_reverseiterator。也就是一个迭代对象。同时,我们使用list©进行输出,发现只能使用一次。第一次输出了元素,第二次为空。那是因为迭代对象在第一次时已经遍历结束了,第二次不能再使用。

注:关于迭代对象的使用,后续章节会进行详细讲解。

10.列表相关的其他内置函数汇

max和min

用于返回列表中最大和最小值。

[ 40 , 30 , 20 , 10 ]

>>>a=[ 3 , 10 , 20 , 15 , 9 ]
>>>max(a)
>>>20
>>>min(a)
>>>3
sum

对数值型列表的所有元素进行求和操作,对非数值型列表运算则会报错。

>>>a=[ 3 , 10 , 20 , 15 , 9 ]
>>>sum(a)
>>>57

11.多维列表

二维列表

一维列表可以帮助我们存储一维、线性的数据。

二维列表可以帮助我们存储二维、表格的数据。例如下表的数据:

姓名年龄薪资城市
高小一1830000北京
高小二1920000上海
高小五2010000深圳

源码:

a=[
	["高小一", 18 , 30000 ,"北京"],
	["高小二", 19 , 20000 ,"上海"],
	["高小一", 20 , 10000 ,"深圳"],
  ]

内存结构图:
在这里插入图片描述

>>>print(a\[1][0],a\[1][1],a\[1][2])
>>>高小二 1920000

嵌套循环打印二维列表所有的数据(mypy_ 08 .py)(由于没有学循环,照着敲一遍即可):

a=[
["高小一", 18 , 30000 ,"北京"],
["高小二", 19 , 20000 ,"上海"],
["高小一", 20 , 10000 ,"深圳"],
]
for m in range( 3 ):
	for n in range( 4 ):
		print(a[m][n],end="\t")
	print()#打印完一行,换行

运行结果:
高小一 18 30000 北京
高小二 19 20000 上海
高小一 20 10000 深圳

12.元组tuple

列表属于可变序列,可以任意修改列表中的元素。元组属于不可变序列,不能修改元组中的元素。因此,元组没有增加元素、修改元素、删除元素相关的方法。

因此,我们只需要学习元组的创建和删除,元组中元素的访问和计数即可。元组支持如下操作:

1 .索引访问

2 .切片操作

3 .连接操作

4 .成员关系操作

5 .比较运算操作

6 .计数:元组长度len()、最大值max()、最小值min()、求和sum()等。

元组的创建

1 .通过()创建元组。小括号可以省略。

a=( 10 , 20 , 30 ) 或者 a= 10 , 20 , 30
如果元组只有一个元素,则必须后面加逗号。这是因为解释器会把( 1 )解释为整数 1 ,( 1 ,)
解释为元组。

>>>a=( 1 )
>>>type(a)
>>><class'int'>
>>>a=( 1 ,) #或者 a= 1 ,
>>>type(a)
>>><class'tuple'>
>>>2 .通过tuple()创建元组
>>>tuple(可迭代的对象)
>>>例如:
>>>b=tuple() #创建一个空元组对象
>>>b=tuple("abc")
>>>b=tuple(range( 3 ))
>>>b=tuple([ 2 , 3 , 4 ])

总结:
tuple()可以接收列表、字符串、其他序列类型、迭代器等生成元组。
list()可以接收元组、字符串、其他序列类型、迭代器等生成列表。

元组的元素访问和计数

1 .元组的元素不能修改

>>>a=( 20 , 10 , 30 , 9 , 8 )
>>>a[ 3 ]= 33
Traceback(mostrecentcalllast):
File"<pyshell# 313 >",line 1 ,in<module>
a[ 3 ]= 33
TypeError:'tuple'objectdoesnotsupportitemassignment

2 .元组的元素访问和列表一样,只不过返回的仍然是元组对象。

>>>a=( 20 , 10 , 30 , 9 , 8 )
>>>a[ 1 ]
>>>10
>>>a[ 1 : 3 ]
>>>( 10 , 30 )
>>>a[: 4 ]
>>>( 20 , 10 , 30 , 9 )
>>>3 .列表关于排序的方法list.sorted()是修改原列表对象,元组没有该方法。如果要对元组排
>>>序,只能使用内置函数sorted(tupleObj),并生成新的列表对象。
>>>a=( 20 , 10 , 30 , 9 , 8 )
>>>sorted(a)
>>>[ 8 , 9 , 10 , 20 , 30 ]
zip

zip(列表 1 ,列表 2 ,…)将多个列表对应位置的元素组合成为元组,并返回这个zip对象。

>>>a=[ 10 , 20 , 30 ]
>>>b=[ 40 , 50 , 60 ]
>>>c=[ 70 , 80 , 90 ]
>>>d=zip(a,b,c)
>>>list(d)
>>>[( 10 , 40 , 70 ),( 20 , 50 , 80 ),( 30 , 60 , 90 )]
生成器推导式创建元组

从形式上看,生成器推导式与列表推导式类似,只是生成器推导式使用小括号。列表推导式直接生成列表对象,生成器推导式生成的不是列表也不是元组,而是一个生成器对象。

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

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

>>>s=(x* 2 forxinrange( 5 ))
>>>s
>>><generatorobject<genexpr>at 0 x 0000000002 BDEB 48 >
>>>tuple(s)
>>>( 0 , 2 , 4 , 6 , 8 )
>>>list(s) #只能访问一次元素。第二次就为空了。需要再生成一次
>>>[]
>>>s
>>><generatorobject<genexpr>at 0 x 0000000002 BDEB 48 >
>>>tuple(s)
>>>()
>>>s=(x* 2 forxinrange( 5 ))
>>>s.__next__()
>>>0
>>>s.__next__()
>>>2
>>>s.__next__()
>>>4
元组总结

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

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

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

13.字典介绍

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

​ 列表中我们通过“下标数字”找到对应的对象。字典中通过“键对象”找到对应的“值对象”。“键”是任意的不可变数据,比如:整数、浮点数、字符串、元组。但是:列表、字典、集合这些可变对象,不能作为“键”。并且“键”不可重复。

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

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

​ a={‘name’:‘gaoqi’,‘age’: 18 ,‘job’:‘programmer’}

14.字典的创建

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 ,'techer']
>>>d=dict(zip(k,v))
>>>d
>>>{'name':'gaoqi','age': 18 ,'job':'techer'}

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

>>>a=dict.fromkeys(['name','age','job'])
>>>a
>>>{'name':None,'age':None,'job':None}

15.字典元素的访问

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

​ a={‘name’:‘gaoqi’,‘age’: 18 ,‘job’:‘programmer’}

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

>>>a={'name':'gaoqi','age': 18 ,'job':'programmer'}
>>>a['name']
'gaoqi'
>>>a['age']
18
>>>a['sex']
Traceback(mostrecentcalllast):
File"<pyshell# 374 >",line 1 ,in<module>
a['sex']
KeyError:'sex'

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

>>>a.get('name')
>>>'gaoqi'
>>>a.get('sex')
>>>a.get('sex','一个男人')
>>>'一个男人'
>>>3 .列出所有的键值对
>>>a.items()
>>>dict_items([('name','gaoqi'),('age', 18 ),('job','programmer')])

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

>>>a.keys()
>>>dict_keys(['name','age','job'])
>>>a.values()
>>>dict_values(['gaoqi', 18 ,'programmer'])

5 .len()键值对的个数
6 .检测一个“键”是否在字典中

>>>a={"name":"gaoqi","age": 18 }
>>>"name"ina
>>>True

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

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

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

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

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

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

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

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

>>>a={'name':'gaoqi','age': 18 ,'job':'programmer'}
>>>a.popitem()
('job','programmer')
>>>a
{'name':'gaoqi','age': 18 }
>>>a.popitem()
('age', 18 )
>>>a
{'name':'gaoqi'}

17.序列解包

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

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

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

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

18.表格数据使用字典和列表存储,并实现访问

姓名年龄薪资城市
高小一1830000北京
高小二1920000上海
高小五2010000深圳

源代码(mypy_ 09 .py):

r 1 ={"name":"高小一","age": 18 ,"salary": 30000 ,"city":"北京"}
r 2 ={"name":"高小二","age": 19 ,"salary": 20000 ,"city":"上海"}
r 3 ={"name":"高小五","age": 20 ,"salary": 10000 ,"city":"深圳"}

tb=[r 1 ,r 2 ,r 3 ]

#获得第二行的人的薪资
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"))

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

​ 字典对象的核心是散列表。散列表是一个稀疏数组(总是有空白元素的数组),数组的每个单元叫做bucket。每个bucket有两部分:一个是键对象的引用,一个是值对象的引用。
​ 由于,所有bucket结构和大小一致,我们可以通过偏移量来读取指定bucket。
在这里插入图片描述

将一个键值对放进字典的底层过程
>>>a={}
>
>a["name"]="gaoqi"
>假设字典a对象创建完后,数组长度为 8 :

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

>>>bin(hash("name"))
>>>'- 0 b 1010111101001110110101100100101 '

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

扩容

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

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

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

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

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

>>>bin(hash("name"))
>>>'- 0 b 1010111101001110110101100100101 '

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

用法总结:

1 .键必须可散列
( 1 ) 数字、字符串、元组,都是可散列的。
( 2 ) 自定义对象需要支持下面三点:
① 支持hash()函数
② 支持通过__eq__()方法检测相等性。
③ 若a==b为真,则hash(a)==hash(b)也为真。

2 .字典在内存中开销巨大,典型的空间换时间。
3 .键查询速度很快
4 .往字典里面添加新建可能导致扩容,导致散列表中键的次序变化。因此,不要在遍历字
典的同时进行字典的修改。

20.集合

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

集合创建和删除

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

>>>a={ 3 , 5 , 7 }
>>>a
>>>{ 3 , 5 , 7 }
>>>a.add( 9 )
>>>a
>>>{ 9 , 3 , 5 , 7 }
>>>
>>>2 .使用set(),将列表、元组等可迭代对象转成集合。如果原来数据存在重复数据,则只保
>>>留一个。
>>>a=['a','b','c','b']
>>>b=set(a)
>>>b
>>>{'b','a','c'}

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

>>>a={ 10 , 20 , 30 , 40 , 50 }
>>>a.remove( 20 )
>>>a
>>>{ 10 , 50 , 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 }

欢迎扫描微信添加,技术交流+资源分享

ID: Txtechcom

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值