列表
创建列表列表元素的增加和删除列表元素的访问和计数列表的切片slice操作列表排序 多维列表
二维列表 元组
元组的创建
元组元素的访问和计数 字典
字典的创建字典元素的访问字典元素添加、修改、删除序列解包字典核心底层原理(重要)将一个键值对放进字典的底层过程根据键查找“键值对”的底层过程 集合
集合的创建和删除集合相关操作
序列是一种数据存储方式,序列中存储的是整数对象的地址么人不是整数对象的值。Python中常用序列结构有:字符串,列表,元组,字典,集合。
列表 用于存储关于任意数目,任意类型的数据集合。是内置可变序列,包含多个元素的有序连续的内存空间。
字符串和列表都是序列类型,字符串是字符序列,列表是任何元素的序列。字符串的许多方法,在列表中也有类似的用法,几乎一模一样。
a = [1,'a',23,'sherry']
list()创建将任何可迭代数据转化为列表。
a = list() #创建空列表 a = list('sherry') #将序列对象转换为列表对象 a = list(range(10)) #将整数序列创建为列表
range()创建创建整数列表。
range([start,] end [,step])推导式生成
a = [x*2 for x in range(5)] #循环创建多个元素a = [x*2 for x in range(100) if x%9 == 0] #通过if过滤元素
列表元素的增加和删除我们一般在列表的尾部添加或删除元素,以大大提高列表的操作效率。
元素增加append()方法:在列表尾部添加对象。
+运算符操作:创建新的列表对象,将原列表的元素和新列表的元素复制到新的列表对象中。
extend()方法:将目标列表的所有元素添加到本列表的尾部,原地操作,不创建新对象 【推荐使用】。
insert()方法:将指定元素插入到列表任意位置,会导致插入位置后的列表的元素移动,会影响处理速度。 涉及大量运算时应避免使用。
乘法扩展:生成一个新列表,新列表元素是原列表元素的多次重复。
a = list()a = list('abc') # a = ['a','b','c']a.append(10)#在列表尾部添加对象10a = a + ['b','c'] #创建新对象,赋值a和['b','c']元素a.extend([50,60]) #尾部插入列表[50,60],推荐使用a.insert(2,'sherry') #在位置2添加元素'sherry' b = a*3 #将a的内容赋值3次
元素删除del 删除:删除位置元素全部前移
pop()方法:删除并返回指定位置元素,如果未包含指定位置则默认操作列表最后一个元素(从尾部弹出)。
remove()方法:删除首次出现的指定元素,若不存在该元素则抛出异常。
a = range(5) # a = [0,1,2,3,4]del a[0] # a = [1,2,3,4]b = a.pop(1) # a = [1,3,4] b = 2a = [10,20,30,10,20,30]a.remove(20) # a = [10,30,10,20,30]a.remove('sherry') #抛出异常
列表元素的访问和计数 通过索引直接访问元素列表索引范围是[0,len-1],超出这个范围则会抛出异常。index()获得指定元素在列表中首次出现的索引
index(value,[start,[end]])
a = [10,20,30,10,20,30]a.index(20) #返回1a.index(20,3,len(a) #返回4
count()获得指定元素在列表中出现的次数a = [10,20,30,10,20,30]a.count(20) #返回2
len()返回列表的长度a = [10,20,30,10,20,30]b = len(a) # b=6
成员资格的判断判断列表中是否存在指定的元素,一般使用in关键词。
a = [10,20,30,10,20,30]b = 10 in a # b= Truec = 'sherry' in a # c = False
列表的切片slice操作 切片slice操作可以让我们快速提取子列表或者修改。标准格式:
列表[起始偏移量 start:终止偏移量 end [:步长 step]]
切片操作,起始偏移量和终止偏移量不在[0,len-1]范围也不会报错。
起始偏移量和终止偏移量要么同为正数,要么同为负数。
修改原列表,不建新列表的排序
· sort():默认升序排列
· sort(reverse=True):降序排列
import randoma = list(range(10))[::-1] # a = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]a.sort() # 升序排序 a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]a.sort(reverse=True) #降序排列 a = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]random.shuffle(a) #打乱列表顺序
建新列表的排序
内置函数sorted()生成新的列表对象
a = list(range(10))[::-1] # a = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]b = sorted(a) # 升序排序 b = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], a无变化c = sorted(b,reverse=True) #降序排列 c = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0], b无变化
reversed()返回迭代器
内置函数reversed()也支持进行逆序排列,不对原列表做任何修改,只是返回一个逆序排列的迭代器对象。
max()和min()函数返回列表中的最大值和最小值,sum()对数值型列表所有元素求和,对非数值型列表报错。
a = list(range(10)) # a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]b = max(a) # b = 9c = min(a) # c = 0d = sum(a) # d = 45
多维列表 二维列表 一维列表可以帮助我们存储一维、线性的数据。
二维列表可以帮助我们存储二维、表格的数据。例如:
a = [["高小一",18,30000,"北京"], ["高小二",19,20000,"上海"], ["高小一",20,10000,"深圳"],]b = a[0] # b = ["高小一",18,30000,"北京"]b = a[0]2] # b = 30000
内存结构图:
列表属于可变序列,可以修改列表中的元素。元组属于有序不可变序列,不能修改元组中的元素,因此没有删除、修改、删除元组元素的相关方法。 列表和元组都可以包含任意对象。
因此只需学习元组的创建,和删除,以及元素中元素的访问和计数等。
元组支持如 下操作:
1.索引访问
2、切片操作
3、连接操作
4、成员关系操作
5、比较运算操作
6、计数:元组长度 len()、最大值 max()、最小值 min()、求和 sum()等。
如果元组只有一个元素,则后面必须加逗号,因为解释会把例如(3)解释成整数3,把(‘abc’)解释成字符串’abc’。
a = (1,2,3,4)a = (1,)a = ('a',)
通过tuple()创建元组b = tuple()b = tuple('abc') # b = ('a','b','c')b = tuple(range(5)) # b= (0,1,2,3,4)b = tuple(['abc',2,3]) # b = ('abc',2,3)
生成器推导式创建元组从形式上看,生成器推导式与列表推导式类似,只是中括号换成了小括号。并且列表推导式直接生成列表对象,而生成器推导式生成的既不是列表也不是元组,而是一个生成器对象。
我们可以通过生成器对象,转化为列表或者元组,也可以使用生成器对象的__next__()方法进行遍历,或者直接作为迭代器对象来使用。不管什么方式使用,元素访问结束后,如果需要重新访问其中的元素,必须重新创建该生成器对象。
s = (x*2 for x in range(5)) #s为生成器对象b = tuple(s) # b = (0,2,4,6,8)c = list(s) # c = [] 已经迭代完了,需要重新创建该生成器对象s = (x*2 for x in range(5)) #s为生成器对象s.__next__() # 0s.__next__() # 2s.__next__() # 4s.__next__() # 6s.__next__() # 8s.__next__() # 报错
总结:
tuple()可以接收列表、字符串、其他序列类型、迭代器等生成元组。
list()可以接收元组、字符串、其他序列类型、迭代器等生成列表。
a = (1,2,3,4)a[0] = 10 # 报错b = a[0:3] # b = (1,2,3)
列表关于排序的方法 list.sorte()是修改原列表对象,元组没有该方法。如果要对元组排序,只能使用内置函数 sorted(tupleObj),并生成新的列表对象。
a = (1,2,3,4)b = sorted(a, reverse=True) # b = (4,3,2,1)
zip(列表 1,列表 2,…)将多个****列表对应位置的元素组合成为元组,并返回这个 zip 对象。
a = [1,2,3]b = [4,5,6]c = [7,8,9]d = zip(a,b,c) #zip对象e = list(d) # e=[(1,2,3),(4,5,6),(7,8,9)] 原列表转换成了元组
元组总结
1.元组的核心特点是:不可变序列。
2.元组的访问和处理速度比列表快。
3、与整数和字符串一样,元组可以作为字典的键,列表则永远不能作为字典的键使用。
字典是“键值对”的无序可变序列。“键”是任意的不可变数据,比如:整数、浮点数、字符串、元组。但是:列表、 字典、集合这些可变对象,不能作为“键”。并且“键”不可重复。 “值”可以是任意的数据,并且可重复。
字典的创建 通过{}、dict()创建字典a = {'name':'sherry','age':24,1:2}b = dict(name='sherry', age=24)c = dict([('name':'sherry'),('age',24),(1,2)])
通过zip()创建字典对象k = ['name','age']v = ['sherry',24]d = dict(zip(k,v))
通过fromkeys创建简直为空的字典a = dict.fromkeys(['name','age',1]) # a = {'name': None, 'age': None, 1: None}b = dict.fromkeys([1,2,3]) # b = {1: None, 2: None, 3: None}
字典元素的访问 通过 [键] 获得“值”。若键不存在,则抛出异常。a = {'name':'sherry','age':24,1:2}name = a['name'] #name = 'sherry'
通过 get()方法获得“值”。推荐使用。指定键不存在,返回 None。也可以设 定指定键不存在时默认返回的对象。a = {'name':'sherry','age':24,1:2}age = a.get('age') # age = 24value = a.get('sex','not found') # value = 'not found'
列出所有的键值对a = {'name':'sherry','age':24,1:2}items = a.items() # items = dict_items([('name', 'sherry'), ('age', 24), (1, 2)])
列出所有的键,列出所有的值a = {'name':'sherry','age':24,1:2}keys = a.keys()# keys = dict_keys(['name', 'age', 1])values = a.values() # values = dict_values(['sherry', 24, 2])
len() 键值对的个数a = {'name':'sherry','age':24,1:2}num = len(a) # num = 3
检测一个“键”是否在字典中关键字 in
a = {'name':'sherry','age':24,1:2}b = 'sex' in a # b = False
字典元素添加、修改、删除 给字典添加“键值对”如果“键”已经存在,则覆盖旧的键值对;如果“键”不存在, 则新增“键值对”。
a = {'name':'sherry','age':24,1:2}a['sex'] = 'female' # a = {'name': 'sherry', 'age': 24, 1: 2, 'sex': 'female'}
使用 update()将新字典中所有键值对全部添加到旧字典对象上。如果 key 有重复,则直 接覆盖。a = {'name':'sherry','age':24,1:2}b = {'sex':'female', 'age':25}a.update(b) # a = {'name': 'sherry', 'age': 25, 1: 2, 'sex': 'female'}
字典中元素的删除,可以使用 del()方法;或者 clear()删除所有键值对;pop()删除指定 键值对,并返回对应的“值对象”;(和列表操作一致)a = {'name': 'sherry', 'age': 25, 1: 2, 'sex': 'female'}del a[1] # a = {'name': 'sherry', 'age': 25, 'sex': 'female'}b= a.pop('sex') # a = {'name': 'sherry', 'age': 25} b = 'female'a.clear() # a = []
popitem()随机删除和返回该键值对.字典是“无序可变序列”,因此没有第一个元 素、最后一个元素的概念;popitem 弹出随机的项,因为字典并没有"最后的元素"或者其 他有关顺序的概念。若想一个接一个地移除并处理项,这个方法就非常有效(因为不用首先获取键的列表)。 序列解包
序列解包可以用于元组、列表、字典。序列解包可以方便地对多个变量赋值。
x,y,z = (1,2,3) # x = 1, y = 2, z = 3(x,y,z)= (1,2,3) # x = 1, y = 2, z = 3[x,y,z] = [1,2,3] # x = 1, y = 2, z = 3a = {'name':'sherry','age':24}name,age = a # 默认对键进行解包 name = 'name' age='age'name,age = a.items() # 对键值对进行解包 name = ('name','sherry') age=('age',24name,age = a.values() # 对值进行操作 name='sherry' age = 24
字典核心底层原理(重要) 字典对象的字典对象的核心是散列表。散列表是一个稀疏数组(总是有空白元素的数组),数组的 每个单元叫做 bucket。每个 bucket 有两部分:一个是键对象的引用,一个是值对象的引 用。由于,所有 bucket 结构和大小一致,我们可以通过偏移量来读取指定 bucket。
根据键查找“键值对”的底层过程
和存储的底层流程算法一致,也是依次取散列值的不同位置的数字。 假设数组长度为 8,我们可以拿计算出的散列值的最右边 3 位数字作为偏移量,即“101”,十进制是数字 5。我们查看偏移量 5,对应的 bucket 是否为空。如果为空,则返回 None。如果不为空, 则将这个 bucket 的键对象计算对应散列值,和我们的散列值进行比较,如果相等。则将对 应“值对象”返回。如果不相等,则再依次取其他几位数字,重新计算偏移量。依次取完后, 仍然没有找到。则返回 None。流程图如下:
总结:
(1) 数字、字符串、元组,都是可散列的。
(2) 自定义对象需要支持下面三点:
@支持 hash()函数
@支持通过__eq__()方法检测相等性。
@若 a==b 为真,则 hash(a)==hash(b)也为真。字典在内存中开销巨大,典型的空间换时间。键查询速度很快往字典里面添加新建可能导致扩容,导致散列表中键的次序变化。因此,不要在遍历字 典的同时进行字典的修改。 集合
集合是无序可变,元素不能重复。实际上,集合底层是字典实现,集合的所有元素都是字典 中的“键对象”,因此是不能重复的且唯一的。
集合的创建和删除 使用{}创建集合对象,并适应add方法添加元素a = {1,2,3}a.add(10) # a = {10,1,2,3}a.add('a') # a = {1, 2, 3, 10, 'a'}
使用 set(),将列表、元组等可迭代对象转成集合。如果原来数据存在重复数据,则只保 留一个。a = [1,2,3]b = set(a) # b = {10,1,2,3}
remove()删除指定元素;clear()清空整个集合(没有del)a = {1,2,3}del a[1] #报错a.remove(1) # a = {2,3}a.clear() # a = {}
集合相关操作交集(& intersection),差集(- difference),并集(| union)。
a = {1,2,3}b = {3,4,5}r = a&b # 求交集 r = {3}r = a | b # 求并集 r = {1,2,3,4,5}r = a-b #求差集 a中有,b中没有 r = {1,2}r = a.intersection(b) # 求交集 r = {3}r = a.union(b) # 求并集 r = {1,2,3,4,5}r = a.difference(b) #求差集 a中有,b中没有 r = {1,2}