目录
组合数据类型及其内置函数
1 序列的操作
1.1 序列的通用操作
1.2 元组 tuple
1.3 列表 list
1.3.1 列表基本操作
1.3.2 列表方法
2 映射类型
2.1 字典 dict
2.2 Counter容器
3 集合类型——集合 set
3.1 基本概念和特点
3.2 相关函数
组合数据类型及其内置函数
顾名思义,组合数据类型就是很多数据组合到一起的数据类型
python的组合数据类型有三种:
- 序列类型:分为元组和列表
- 映射类型:主要是字典类型
- 集合类型:主要是集合类型
python的具体组合数据类型一共有4种:
- tuple 元组 不可变数据类型
- list 列表 可变
- dict 字典 可变
- set 集合
这四种数据类型各有差异。
1 序列的操作
序列结构包含:
- 元组
- 列表
- 字符串
这里讲的是组合数据类型,所以字符串类型就不讲了。
1.1 序列的通用操作
元组和列表都是序列结构,他们的区别是元组不可变,列表可变,故除了改变元素的方法之外,他们的很多操作是相同的,例如:
- 索引
- 切片
- 拷贝
- 相加
- 相乘
- 成员资格检查
- ……
1.1.1 索引
序列中所有的元素都有编号,从0开始,到length-1结束,可以使用[]
来访问指定位置的元素。
- index > 0时,从前往后数
- index = 0时,为第一个元素
- index < 0时,从后往前数,[-1]是指最后一个元素,[-2]是指倒数第二个元素
1.1.2 切片
序列可以用索引访问单个元素,也可以用切片操作来访问特定范围的元素。
- 使用
[start: stop]
对序列进行切片,切片范围是[start, stop),包含index=start,不包含index=stop
a = (0,1,2,3,4,5,6,7,8,9,10)
print(a[1:5] # (1, 2, 3, 4) ,切片范围是[1,5)
b = a[-3:-1] # b=(8,9)
b = a[-3:] # b=(8,9,10)
- 使用
b = a[-3:-1]
获取序列中最后3个元素是行不通,因为index=-1是范围上限并没有被包含在取值范围呢,必须使用b = a[-3:]
,表示从倒数第三个元素直到最后一个元素 - 序列尾部可以使用省略写法
b = a[-3:]
,序列开头也可以使用省略写法b = a[:-3]
表示从开头直到倒数第3个元素。不过这和b = a[1:-3]
没有区别。 - 使用省略写法
b = a[:]
表示b提取了a中所有的元素,即拷贝了整个序列 - 切片还可以指定步长,用法:
[start:stop:step]
,使用这种方法可以实现很多功能,比如取奇偶数,取间隔数,取逆
a = tuple(range(10)) # (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
b = a[::2] # (0, 2, 4, 6, 8) 偶数
c = a[1::2] # (1, 3, 5, 7, 9) 奇数
d = a[::-1] # (9, 8, 7, 6, 5, 4, 3, 2, 1, 0) 取逆
e = a[::-2] # (9, 7, 5, 3, 1) 逆奇数
1.1.3 拷贝
个人理解:python用=
进行赋值操作,很多时候赋予的都是“变量的地址”而不是“值”
- 对序列进行拷贝需要使用切片提取出序列的所有值后赋给新变量
>>> l1 = [1,2,3]
>>> l2 = l1
>>> id(l1)
1401388290952
>>> id(l2)
1401388290952 # 直接赋值的变量地址相同
>>> l3 = l1[:] # 创建了新的变量
>>> id(l3)
1401418052744 # 新的变量有新的地址值,与原来的变量互不干扰
1.1.4 序列相加(拼接)
序列可以使用+
运算符进行拼接操作。但是不能拼接不同的序列类型,列表,元组,字符串之间互相不能拼接
>>> [1,2,3]+[4,5,6]
[1, 2, 3, 4, 5, 6]
>>> [1,2,3]+'456'
TypeError: can only concatenate list (not "str") to list
>>> ('123',)+('456',)
('123', '456')
1.1.5 序列乘法(倍增)
序列可以通过乘以一个正整数n,将本身扩展成n倍。
- 空列表不包含任何元素,扩展n倍后还是空列表
- 想要创建一个不包含有用内容,但长度为n的列表,可以用占位元素定义一个长度为1的列表再乘以n,比如
None
或者其他无用元素
>>> [1,2,3]*3
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> 'pyhton'*3
'pyhtonpyhtonpyhton'
>>> []*10
[]
>>> [None]*10
[None, None, None, None, None, None, None, None, None, None]
>>> [0]*3
[0, 0, 0]
1.1.6 成员资格检查
用in
运算符检查元素是否在序列中,返回值为True或者False
>>> 'p' in 'python'
True
>>> 'c' in 'python'
False
>>> 3 in [1,2,3]
True
1.1.7 其他用法
1.2 元组 tuple
1.2.1 元组的基本概念和特性
元组可以存放任意数据类型,元组的特性在于不可改变,一旦数据定义之后就不可以更改了
- 多用于确保数据安全,不让数据被修改的场景
- 元组用圆括号()进行创建
- 元组可以用tuple()将其他一维数据转换成元组
- 元组元素不能被修改,但是元组嵌套其他可变组合数据类型后,元组的元素的元素可以被修改。猜测:是因为元组被定义后的元素地址不可被更改。
a = [1, 2]
b = [3, 4]
tup = (a, b)
print(tup) # ([1, 2], [3, 4])
tup[1][1] = 10
print(tup) # ([1, 2], [3, 10])
1.2.2 元组的常用内置方法
1.2.2.1 定义
注意:单个内容转换元组是不成功的,需要加个逗号,
- 用
,
将一些值分隔就能得到一个元组
>>> a = 1,2,3
>>> a
(1, 2, 3)
>>> type(a)
<class 'tuple'>
- 当用
()
定义元组时,决定得到的结果是不是元组的关键是,
t = ('abc') # 含义:'abc'作为一个元素,定义一个元组
print(t,type(t),len(t)) # abc <class 'str'> 3
t1 = ('abc',)
print(t1,type(t1),len(t1)) # ('abc',) <class 'tuple'> 1
t2 = tuple('abc') # t2=('a','b','c') 含义是将'abc'这个字符串转换成元组
- 函数tuple()定义元组,他将一个序列作为参数,将其转换成元组,如果参数已经是元组,就直接返回它
tup = tuple(1,2,3)
tup = (2,3,4)
li = [1,2,3]
tup = tuple(li) # tup = (1,2,3)
1.2.2.2 tuple.count()
功能:返回元组中某个元素的出现次数
def count(self, value, /)
Return number of occurrences of value.
pass
tup = (1,2,1,2,3)
print(tup.count(2)) # 2
1.2.2.3 tuple.index()
功能:返回元组中第一次出现元素的位置,没有元素则报错
可以手动设置搜索元素的范围 [start, stop),包含start,不包含end的位置
def index(self, value, start=0, stop=9223372036854775807, /)
Return first index of value.
Raises ValueError if the value is not present.
pass
tup = (1,2,3,2,3)
print(tup.index(2)) # 1
print(tup.index(2,2,4)) # 3
print(tup.index(2,3,4)) # 3 包含start的位置
print(tup.index(2,2,3)) # ValueError: tuple.index(x): x not in tuple 不包含stop的位置
1.3 列表 list
列表可以执行所有序列通用操作,切片、相加、相乘等,它与元组最大的区别是它可以改变它的元素值。
1.3.1 列表基本操作
特别知识点:
- 访问
lst[len(lst)]
会报错,但是lst[len(lst):] = b
表示在lst末尾添加值 会成功
>>> lst = [1,2]
>>> lst[len(lst):]=[3,4]
>>> lst
[1, 2, 3, 4]
>>> lst[len(lst)]
IndexError: list index out of range
1.3.1.1 列表定义
- 使用方括号
[]
进行定义 - 使用list()函数进行定义
x = [1,2,3]
x = list('abc') # x = ['a', 'b', 'c']
1.3.1.2 修改列表:给列表赋值
- 修改元素,对列表可以用索引直接定位一位元素进行修改
x[2] = 3
- 删除元素,用
del
关键字,指定一个确定位置的元素进行删除
del x[2]
- 切片与切片赋值,在不可变的序列(元组,字符串)中,切片只能用于提取元素,在列表中,切片还可以用于更改元素,例如将一个切片元素改为其他值,将一个切片的元素改为空值,也就是删除这个切片
l = list('马冬梅')
print(l) # ['马', '冬', '梅']
l[0:1] = list('什么')
print(l) # ['什', '么', '冬', '梅']
l[3:] = list('什么')
print(l) # ['什', '么', '冬', '什', '么']
l[:2] = [] # 将[:2]中的元素赋值为空,也是一种删除操作
print(l) # ['冬', '什', '么']
1.3.2 列表方法
方法名 | 功能 |
append(value) | 将value附加到列表末尾 |
clear() | 清空列表的内容,等同于lst[:] = [] |
copy() | 返回一个与列表相同的副本,a=b.copy()等同于a=b[:] |
count(value) | 计算value在列表中出现的次数 |
extend(lst) | 将多个值同时附加到列表末尾,效率比 |
index(value) | 返回列表中第一次出现value的索引 |
insert(loc, value) | 在loc的位置上插入value |
pop() | 删除并返回列表中的最后一个元素 |
remove(value) | 在列表中删除第一个指定的value值,如果没有则报错 没有范围指定,也没有返回值 |
reverse() | 将列表反向排列,没有返回值。 |
sort(cmp=None, key=None, reverse=False) | 对列表就地排序,没有返回值。cmp:排序方法,key:用于比较的元素(可以用函数来返回一个元素),比如元素长度(内置函数len),元素中第二个元素等等,reverse=True 降序, =False升序,默认升序 |
- 补充:
- 想要得到一个reverse或者sort的副本,可以使用reversed() sorted()方法,这两个方法不会改变原来列表。
y=sorted(x)
- extend() 与
+
拼接
+
拼接是将两个列表的元素提出来组成了一个新的列表返回- a.extend(b)是将b中的元素直接添加到了列表a的末尾,相当于a[len(a):] =b
a = [1,2]
b = [2,3]
c = a.extend(b)
print(a, c, id(a),id(c))
# [1, 2, 2, 3] None 1437310865800 140704304422112
d = a+b
print(a, d, id(d))
# [1, 2, 2, 3] [1, 2, 2, 3, 2, 3] 1437312140296
- insert()
a = [1,2]
a.insert(2,[3,4]) # 在索引值为2的位置上插入[3,4]
print(a) # [1,2,[3,4]]
- sort
cmp参数暂不知用法
lst = [[1,5],[3,2],[2,3]]
l1 = lst[:]
l1.sort()
print(l1) # [[1, 5], [2, 3], [3, 2]]
def getSecond(elem):
return elem[1]
l2 = lst[:]
l2.sort(key=getSecond) # sort本身会对每个元素进行处理,指定key=getSecond后,这些元素就会通过getSecond进行处理,默认按元素的第一位进行排序
print(l2) # [[3, 2], [2, 3], [1, 5]]
2 映射类型
2.1 字典 dict
字典类型数据的数据结构是映射,可以通过键来访问值
2.1.1 字典概念
- 字典有键和对应值组成,键-值对成为项item
- 键独一无二,值可以重复
- eg:
stu = {'name': 'zhangsan', 'num': 20190904}
2.1.2 字典创建和定义
- 直接使用大括号定义字典,如
stu = {'name': 'zhangsan', 'num': 20190904}
- 使用函数dict()从其他映射或键值序列创建字典,
>>> name = ['zhangsan', 'lisi']
>>> age = [23, 34]
>>> dic = dict(zip(name, age))
>>> dic
{'zhangsan': 23, 'lisi': 34}
>>> items = [('name', 'Gumby'), ('age', 42)]
>>> d = dict(items)
>>> d
{'name': 'Gumby', 'age': 42}
- 还可以用关键字实参调用dict()
>>> d = dict(name='Gumby', age=42)
>>> d
{'age': 42, 'name': 'Gumby'}
2.1.3 字典基本操作
- len(dic)返回字典dic包含的项数,即长度
- d[key]返回键key相关联的值,字典没有索引,
[]
中的值就是key值, - 字典的key值可以是数字,也可以是字符或字符串,是任意不可变类型的值字符或字符串需要加引号。当数字做key值,不要和索引混淆
>>> dic = {1:100,2.1:103}
>>> dic[1]
100
>>> dic[2.1]
103
d[k] = v
可以将v关联到键k上,如果原来的字典有值为k的键,则将这个键对应的值改为v,否则在字典里新加一对键值对k: v
>>> dic = {'a':3, 'b':4}
>>> dic['e'] = 15
>>> dic
{'a': 3, 'b': 4, 'e': 15}
>>> dic['e'] = -15
>>> dic
{'a': 3, 'b': 4, 'e': -15}
del d[k]
删除键为k的项k in d
检查字典d是否包含键为k的项- 用format_map()函数将字典的对应键的值映射出来
>>> phonebook
{'Beth': '9102', 'Alice': '2341', 'Cecil': '3258'}
>>> "Cecil's phone number is {Cecil}.".format_map(phonebook)
"Cecil's phone number is 3258."
format_map(...)
S.format_map(mapping) -> str
# Return a formatted version of S, using substitutions from mapping.
# The substitutions are identified by braces ('{' and '}').
# 用映射类型中的映射内容替换S中的{},并且映射值由{}中的内容指定
2.1.4 字典方法
方法名 | 功能 |
clear() | 删除所有字典项,原地操作,无返回值,所有指向源地址的字典都会被置为空值 |
copy() | 浅拷贝,值本身是原件,而不是副本(只拷贝了一层),深拷贝用copy模块中的deepcopy |
fromkeys(lst) | 该方法创建了一个新字典,用序列lst的所有值作为新字典的键,每个键对应的值都是None |
get(k) | 访问字典中键为k的值,没有k键,默认返回None,而用 |
items() | 返回一个包含所有字典项的列表,每个元素都为(key,value)的形式,排列顺序不确定。通常用于遍历或迭代 |
keys() | 返回一个字典视图,包含字典中的键 |
values() | 返回一个字典试图,包含字典中的值,可能包含重复的值 |
pop(k) | 用于获取与指定键相关联的值,并将该键-值对从字典中删除。 |
popitem() | popitem随机地弹出并删除一个字典项,类似于list.pop() |
setdefault(k, default_value) | 方法setdefault有点像get,因为它也获取与指定键相关联的值,但除此之外,setdefault还在字典不包含指定的键时,在字典中添加指定的键-值对。 |
update(dic) | 使用一个字典中的项来更新另一个字典 |
iter*() | iterkey(), itervalues(), iteritems())都是行为与它们的非迭代器版本相同的方法,但是返回一个迭代器,而不是一个列表 |
- copy 浅拷贝 元素的元素与原来的字典共用,
- 深拷贝 能拷贝所有内容
from copy import deepcopy
>>> x = {'username': 'admin', 'machines': ['foo', 'bar', 'baz']}
>>> y = x.copy()
>>> y['username'] = 'mlh'
>>> y['machines'].remove('bar')
>>> y
{'username': 'mlh', 'machines': ['foo', 'baz']}
>>> x
{'username': 'admin', 'machines': ['foo', 'baz']}
- fromkeys
>>> {}.fromkeys(['name', 'age'])
{'age': None, 'name': None}
>>> dict.fromkeys(['name', 'age'])
{'age': None, 'name': None}
# 如果你不想使用默认值None,可提供特定的值。
>>> dict.fromkeys(['name', 'age'], '(unknown)')
{'age': '(unknown)', 'name': '(unknown)'}
- get 如果字典包含指定的键,get的作用将与普通字典查找相同,如果不包含,返回
None
或者指定值
>>> d = {}
>>> print(d['name'])
KeyError: 'name'
>>> print(d.get('name'))
None
>>> d.get('name', 'N/A')
'N/A'
- items
- 返回值属于一种名为字典视图的特殊类型。字典视图可用于迭代, 另外,还可确定其长度以及对其执行成员资格检查。
>>> it = d.items()
>>> len(it)
3
>>> ('spam', 0) in it
True
# 视图的一个优点是不复制,它们始终是底层字典的反映,即便你修改了底层字典亦如此。
>>> d['spam'] = 1
>>> ('spam', 0) in it
False
>>> d['spam'] = 0
>>> ('spam', 0) in it
True
- setdefault 类似get,获取与指定键相关联的值,另外,指定的键不存在时,返回指定的值并在字典中添加指定的键-值对。
- 指定值默认为None
>>> d = {}
>>> d.setdefault('name', 'N/A')
'N/A'
>>> d
{'name': 'N/A'}
>>> d['name'] = 'Gumby'
>>> d.setdefault('name', 'N/A')
'Gumby'
>>> d
{'name': 'Gumby'}
- update 使用一个字典中的项来更新另一个字典
>>> d = {1:1, 2:2, 3:3}
>>> x = {2:4, 3:9, 4:16}
>>> d.update(x)
>>> d
{1: 1, 2: 4, 3: 9, 4: 16}
2.2 Counter容器
python-Counter中文文档地址: https://docs.python.org/zh-cn/3/library/collections.html#collections.Counter
2.2.1 Counter基本概念和特点
Counter是字典的子类,提供了可哈希对象的计数功能,
- Counter类从collections包中导入
from collections import Counter
- Counter的元素 {被计数的对象:计数值}
- 被计数的可以是任意可哈希对象(不可变值),包括0,负数
- Counter可以由序列、迭代器或者映射初始化,比如列表,字典等等
- 访问Counter的元素,类似访问字典,访问一个不存在的键,会返回0,不会报错
- 设置一个计数为0不会从计数器中移去一个元素。而是需要使用
del
来删除它
2.2.2 Counter常用函数
函数名 | 功能 |
elements() | 返回一个迭代器,每个元素重复计数值的个数。元素顺序是任意的。如果一个元素的计数小于1, elements() 就会忽略它 |
most_common(n) | 返回一个列表,提供 n 个频率最高的元素和计数。 如果没提供 n ,或者是 |
subtract(iterable-or-mapping) | 减去迭代对象或映射对象中元素 |
update(iterable-or-mapping)) | 加上迭代对象或映射对象中元素,字典中的update()是替换 |
items() | 同字典,返回所有项 |
keys() | 同字典,返回所有键 |
values() | 同字典,返回所有计数值 |
pop(k) | 同字典,返回键为k的项并删除 |
popitem() | 同字典,随机返回并删除一项 |
setdefault(k, default_value) | 同字典,设置一项 |
copy() | 同字典,浅拷贝 |
3 集合类型——集合 set
3.1 基本概念和特点
集合set是一个无序的不重复序列
- 集合内不允许重复的元素
- 集合内没有先后顺序
- 集合可以通过大括号
{}
来定义,里面的元素是单个的,不同于字典的键值对 - 集合的元素必须是可哈希的数据类型,即所有不可变的数据(整数、浮点数、字符串、元组、布尔值)
- 创建一个空集合是用
set()
,{}
表示一个空的字典
python中的集合有两种,
- set:可以动态增加、删除元素的可变集合
- frozenset:元素不可改变,类似元组
注意:对于 并集, 交集, 差集 等的返回值,与最左边的操作数具有相同的类型。例如:s & t 取交集。s集合是一个set类型的集合,t集合是一个frozenset类型的集合,则返回的结果将是set类型的集合
3.2 相关函数
部分函数表
函数名 | 功能 |
set([obj]) | 新建一个可变集合 |
frozenset([obj]) | 新建一个不可变集合 |
add(obj) | 添加 |
remove(obj) | 删除,如果obj不存在则报错 |
discard(obj) | 丢弃,remove的友好版本,不报错 |
pop() | 弹出:删除并返回任意一个元素 |
clear() | 清空 |
copy() | 浅拷贝,不过set的元素也是不可变元素 |
部分函数以及等效操作符
函数名 | 等效操作符 | 功能 |
| s == t / s != t | 是否拥有完全相同的元素 |
| obj in s /obj not in s | 成员检测 |
| s < t | 真子集(严格子集测试) |
s.issubset(t) | s < = t | 子集 |
| s > t | 真超集 |
s.issuperset(t) | s >= t | 超集 |
s.union(t) | s | t | 并 |
s.intersection(t) | s & t | 交 |
s.difference(t) | s - t | 差 |
s.symmetric_difference(t) | s ^ t | 对称差 |
s.update(t) | s |= t | 更新操作(联合更新、并更新),将t的成员添加到中 等同于 |
s.intersection_update(t) | s &= t | 交更新, |
s.difference_update(t) | s -= t | 差更新, |
s.symmetric_difference_update(t) | s ^= t | 对称差更新, |