python基本数据类型
序列简介
类型 | 列表 | 元组 | 字典 | 集合 |
---|---|---|---|---|
类型名称 | list | tuple | dict | set |
定界符 | 方括号[] | 圆括号() | 大括号{} | 大括号{} |
是否可变 | 是 | 否 | 是 | 是 |
是否有序 | 是 | 是 | 否 | 否 |
是否支持下标 | 是(使用序号作为下标) | 是(使用序号作为下标) | 是(使用“键”作为下标) | 否 |
元素分隔符 | 逗号 | 逗号 | 逗号 | 逗号 |
对元素形式的要求 | 无 | 无 | 键:值 | 必须可哈希 |
对元素值的要求 | 无 | 无 | “键”必须可哈希 | 必须可哈希 |
元素是否可重复 | 是 | 是 | “键”不允许重复,“值”可以重复 | 否 |
元素查找速度 | 非常慢 | 很慢 | 非常快 | 非常快 |
新增和删除元素速度 | 尾部操作快,其他位置慢 | 不允许 | 快 | 快 |
列表
- 构造:
通过内置的list函数或者 [] 号
原理:
整个列表是一个储存地址,列表中的元素也有自己的储存地址。改变列表元素,列表地址并未发生改变。
列表的增删原理
列表对象自动进行内存的扩展或收缩,从而保证相邻元素之间没有缝隙。Python列表的这个内存自动管理功能可以大幅度减少程序员的负担,但插入和删除非尾部元素时涉及到列表中大量元素的移动,会严重影响效率。
在非尾部位置插入和删除元素时会改变该位置后面的元素在列表中的索引,这对于某些操作可能会导致意外的错误结果。
除非确实有必要,否则应尽量从列表尾部进行元素的追加与删除操作
列表的取值与切片
取值:一次只能取一个值,下标不可越界
切片:可以顺着切,也可以逆着切,[a🅱️c],a代表起始位置,b代表结束位置。c代表间隔(1,2,-1,-2等)。c为负,逆着数。
使用切片可以返回列表中部分元素组成的新列表。与使用索引作为下标访问列表元素的方法不同,切片操作不会因为下标越界而抛出异常,而是简单地在列表尾部截断或者返回一个空列表,代码具有更强的健壮性。
可以通过切片来进行列表的增删改:
对于间隔为1或-1的连续切片:
增:将该切片的元素赋予一个新的列表值,
比如要在第二个元素(下标为1)后插入元素,那么就是a[1:1]=list
开头:a[:0]=list
结尾:a[len(a):]=list
删:将该切片位置的元素赋予空列表
改:重新赋予元素
如果间隔不为1,即不连续,则列表两边长度必须一致。所以可以进行增加操作,但不可以进行删除操作,修改时,两边元素长度必须相等。
也可以用del函数结合切片来删除元素,可以通过切片来选择元素,通过del函数删除,所以可以删除不连续的元素。
列表的方法
与列表相关函数
max()、min()函数用于返回列表中所有元素的最大值和最小值,
sum()函数用于返回列表中所有元素之和;
len()函数用于返回列表中元素个数
zip()函数用于将多个列表中元素重新组合为元组并返回包含这些元组的zip对象;
enumerate()函数返回包含若干下标和值的迭代对象;
map()函数把函数映射到列表上的每个元素
filter()函数根据指定函数的返回值对列表元素进行过滤;
all()函数用来测试列表中是否所有元素都等价于True,
any()用来测试列表中是否有等价于True的元素。
标准库functools中的reduce()函数以及标准库itertools中的compress()、groupby()、dropwhile()等大量函数也可以对列表进行操作。
列表推导式
列表推导式使用非常简洁的方式来快速生成满足特定需求的列表,代码具有非常强的可读性。
列表推导式语法形式为:
[expression for expr1 in sequence1 if condition1
for expr2 in sequence2 if condition2
for expr3 in sequence3 if condition3
...
for exprN in sequenceN if conditionN]
expression是一个表达式,包括(函数,三元运算等,也可以是嵌套的列表推导式),for循环后面还可以加if条件。可以多个for循环嵌套,最后用[]号括起来即可生成列表推导式,生成一个列表。注意逻辑是先判断循环条件,在计算表达式。
元组
元组与列表各方面都很相似,只不过元素是一个不可变的数据,所以元组不能进行增删改,也没有很多方法,但是它的稳定的性质很有用处。
生成器推导式
生成器推导式(generator expression)的用法与列表推导式非常相似,在形式上生成器推导式使用圆括号(parentheses)作为定界符,而不是列表推导式所使用的方括号(square brackets)。
与列表推导式最大的不同是,生成器推导式的结果是一个生成器对象。生成器对象类似于迭代器对象,具有惰性求值的特点,只在需要时生成新元素,比列表推导式具有更高的效率,空间占用非常少,尤其适合大数据处理的场合。
使用生成器对象的元素时,可以根据需要将其转化为列表或元组,也可以使用生成器对象的__next__()方法或者内置函数next()进行遍历,或者直接使用for循环来遍历其中的元素。但是不管用哪种方法访问其元素,只能从前往后正向访问每个元素,没有任何方法可以再次访问已访问过的元素,也不支持使用下标访问其中的元素。当所有元素访问结束以后,如果需要重新访问其中的元素,必须重新创建该生成器对象,enumerate、filter、map、zip等其他迭代器对象也具有同样的特点。
如果直接访问该对象,则该对象访问一次后就无了,如果是访问其中的一个元素,该元素访问后就无了。下次只能访问之后的元素
字典
字典(dictionary)是包含若干“键:值”元素的无序可变序列,字典中的每个元素包含用冒号分隔开的“键”和“值”两部分,表示一种映射或对应关系,也称关联数组。定义字典时,每个元素的“键”和“值”之间用冒号分隔,不同元素之间用逗号分隔,所有的元素放在一对大括号“{}”中。
字典中元素的“键”可以是Python中任意不可变数据,例如整数、实数、复数、字符串、元组等类型等可哈希数据,但不能使用列表、集合、字典或其他可变类型作为字典的“键”。另外,字典中的“键”不允许重复,而“值”是可以重复的。
字典的创建
- 使用{}号
a={'key1':value1,'key2':value2}
- 使用dict函数
创建空字典:x=dict() 创建有键无值的字典:aDict = dict.fromkeys([’name’, ‘age’, ‘sex’]) 以关键参数的形式创建字典:d = dict(name=‘Dong’, age=39) 根据已有数据创建字典:dictionary = dict(zip(keys, values)),每一个元素必须是二维的,键名重复则合并
字典的访问
只能通过键名,因为是无序的。
字典中的每个元素表示一种映射关系或对应关系,根据提供的“键”作为下标就可以访问对应的“值”,如果字典中不存在这个“键”会抛出异常。
字典对象提供了一个get()方法用来返回指定“键”对应的“值”,并且允许指定该键不存在时返回特定的“值”。例如:
>>> aDict.get('age') #如果字典中存在该“键”则返回对应的“值”
39
>>> aDict.get('address', 'Not Exists.') #指定的“键”不存在时返回指定的默认值
'Not Exists.'
使用字典对象的items()方法可以返回字典的键、值对。
使用字典对象的keys()方法可以返回字典的键。
使用字典对象的values()方法可以返回字典的值。
## 构造
>>> x = dict() #空字典
>>> type(x) #查看对象类型
>>> x = {} #空字典
>>> keys = ['a', 'b', 'c', 'd']
>>> values = [1, 2, 3, 4]
>>> dictionary = dict(zip(keys, values)) #根据已有数据创建字典
>>> d = dict(name='Dong', age=39) #以关键参数的形式创建字典
>>> aDict = dict.fromkeys(['name', 'age', 'sex'])
#以给定内容为“键”,创建“值”为空的字典
>>> print(aDict)
>>> print(dictionary)
>>> print(d)
## 访问
print(d['name'])
>>> print(aDict.get('age') ) #如果字典中存在该“键”则返回对应的“值”
>>> print(aDict.get('address', 'Not Exists.') )#指定的“键”不存在时返回指定的默认值
{'name': None, 'age': None, 'sex': None}
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
{'name': 'Dong', 'age': 39}
Dong
None
Not Exists.
字典的增删改
- 增加或修改元素:
当以指定“键”为下标为字典元素赋值时,有两种含义:
1)若该“键”存在,则表示修改该“键”对应的值;
2)若不存在,则表示添加一个新的“键:值”对,也就是添加一个新元素。
使用字典对象的update()方法可以将另一个字典的“键:值”一次性全部添加到当前字典对象,如果两个字典中存在相同的“键”,则以另一个字典中的“值”为准对当前字典进行更新。
- 删除元素
如果需要删除字典中指定的元素,可以使用del命令。
也可以使用字典对象的pop()和popitem()方法弹出并删除指定的元素
标准库collectios中与字典有关的类
(1)OrderedDict类
Python内置字典dict是无序的,如果需要一个可以记住元素插入顺序的字典,可以使用collections.OrderedDict。
>>> import collections
>>> x = collections.OrderedDict() #有序字典
>>> x['a'] = 3
>>> x['b'] = 5
>>> x['c'] = 8
>>> x
OrderedDict([('a', 3), ('b', 5), ('c', 8)])
(2)defaultdict类
默认字典中的元素
>>> import string
>>> import random
>>> x = string.ascii_letters + string.digits + string.punctuation
>>> y = [random.choice(x) for i in range(1000)]
>>> z = ''.join(y)
>>> from collections import defaultdict
>>> frequences = defaultdict(int) #所有值默认为0
>>> frequences
>>> for item in z:
frequences[item] += 1 #修改每个字符的频次
>>> frequences.items()
dict_items([('\\', 3), ('H', 9), ('5', 11), ('G', 10), ('{', 9), ('j', 15), ('[', 12), ('r', 5), ('`', 9), ('#', 13), ('b', 13), ('<', 18), ('f', 9), ("'", 12), ('O', 14), ('B', 12), ('1', 11), ('=', 11), ('8', 12), ('l', 11), ('k', 16), ('+', 16), ('K', 7), ('x', 11), ('i', 7), ('(', 13), ('L', 9), ('"', 10), ('S', 13), ('C', 13), ('c', 9), ('u', 11), ('|', 8), ('e', 10), ('N', 12), ('4', 19), ('%', 13), ('q', 9), ('~', 6), ('n', 18), ('7', 7), ('W', 13), ('z', 6), ('I', 13), ('/', 16), ('*', 11), ('t', 13), ('?', 7), (':', 8), ('p', 6), ('E', 14), ('.', 6), ('o', 11), ('>', 10), ('d', 14), ('&', 12), ('Y', 7), ('X', 10), (')', 8), ('9', 9), ('y', 11), (']', 13), ('!', 9), ('w', 6), ('m', 7), ('s', 19), ('_', 9), (',', 12), ('^', 11), ('a', 13), ('0', 14), ('J', 9), ('V', 7), ('T', 9), ('2', 15), ('R', 8), ('Z', 9), ('F', 9), ('U', 8), ('P', 11), ('A', 18), ('3', 11), ('M', 12), ('6', 6), ('v', 8), ('h', 10), ('g', 10), (';', 10), ('Q', 15), ('}', 9), ('-', 15), ('@', 9), ('$', 2), ('D', 6)])
(3)Counter类
对于频次统计的问题,使用collections模块的Counter类可以更加快速地实现这个功能,并且能够提供更多的功能,例如查找出现次数最多的元素。
>>> from collections import Counter
>>> frequences = Counter(z) #这里的z还是前面代码中的字符串对象
>>> frequences.items()
>>> frequences.most_common(1) #返回出现次数最多的1个字符及其频率
>>> frequences.most_common(3) #返回出现次数最多的前3个字符及其频率
[('4', 19), ('s', 19), ('<', 18)]
集合
集合(set)属于Python无序可变序列,使用一对大括号作为定界符,元素之间使用逗号分隔,同一个集合内的每个元素都是唯一的,元素之间不允许重复。 集合中只能包含数字、字符串、元组等不可变类型(或者说可哈希)的数据,而不能包含列表、字典、集合等可变类型的数据。
创建集合
set函数,或者{}号
增删改
使用集合对象的add()方法可以增加新元素,如果该元素已存在则忽略该操作,不会抛出异常;
update()方法用于合并另外一个集合中的元素到当前集合中,并自动去除重复元素。
pop()方法用于随机删除并返回集合中的一个元素,如果集合为空则抛出异常;
remove()方法用于删除集合中的元素,如果指定元素不存在则抛出异常;
discard()用于从集合中删除一个特定元素,如果元素不在集合中则忽略该操作;
clear()方法清空集合删除所有元素。
序列解包
- 可以使用序列解包功能对多个变量同时进行赋值。
- 交换两个变量的值
- 对range对象,迭代器,生成器对象解包,字符串,列表,元组,字典,集合(字典和集合的元素没有顺序)等都可以解包
四种序列的转化
- 转化成列表:
集合,元组,range对象,迭代器,生成器,map,zip,filter,enumerate等对象,字符串,可以直接使用list函数生成列表,字典直接套用list函数是键生成列表,也可以利用字典的方法,生成关于值或键值对的列表。
- 转化成元组:
与列表类似
- 转化成集合:
也可以使用函数set()函数将列表、元组、字符串、range对象等其他可迭代对象转换为集合,如果原来的数据中存在重复元素,则在转换为集合的时候只保留一个;如果原序列或迭代对象中有不可哈希的值,无法转换成为集合,抛出异常。
- 转化成字典:
需要键值可哈希并且成对。