一、前言
python中包含一种叫做容器(container)的数据结构。容器上基本上是包含其他对象的任意对象。序列和映射是两种主要的容器,还有一种既不是序列也不是映射的,比如集合。下面所有的介绍主要是针对python3的。
-
序列
py内置6种序列,所谓的序列就是数据是有序的,可以通过索引唯一确定。常用的有列表、元组、字符串/Unicode字符串(py2中都是是8位是ASCII编码存储,也就是只能表示128个字符,py3中所有字符串都是16位存储的unicode字符串,可以表示65536个字符)。另外还有buffer对象、xrange对象。 -
映射
映射是可以通过名字进行引用值的数据结构。py中唯一内置的映射类型是字典。字典中的值没有顺序,并且都是成对出现key-val(键值对)。key表示键,在字典中是唯一的,可以是数字、字符串、元组等;val就是具体的值了,可以是数字、列表、字符串、对象等。 -
集合
集合是由序列(或其他可迭代的对象)构建的,同字典一样是无序的(无序,即没有一定的顺序,不能通过索引查找)。主要用于检查成员资格,因此副本被忽略。(想象一下数学里面的集合,含义相同,元素唯一、无序)。
下面主要介绍列表、元组、字典、集合这几种数据结构。
二、序列
所有的序列类型数据都可以进行一些特定的操作:索引(indexing)、分片(slicing)、加(adding)、乘(multipliing)、迭代(iteration)以及检查某个元素是否属于某个序列(in)。此外,还可以进行长度(len)、最大元素(max)、最小元素(min)等操作。
- 索引
序列中元素下标都是从0开始,可以通过编号访问
>>>num = [1,2,3,4,5]
>>>num[0]
1
>>>num[-1]
5
>>>name = "wang-jue"
>>>name[4]
'-'
- 分片
分片是通过索引的位置访问一定范围内的元素,中间用冒号分割,元素包含起始位,不包含最终位,默认步长是1。并且起始位和最终位是按照先后顺序的。如果切片的起始位和最终位不符合要求或者越界,返回空。
num[start:end:step],start默认是0(包含),end默认是最后一个(不包含),step默认是1。
>>>num = [1,2,3,4,5]
>>>num[1:3]
[2,3]
>>>num[-3:-1]
[3,4]
>>> num[1:10]
[2, 3, 4, 5]
>>> num[6:10]
[]
>>>num[-1:-3]
[]
>>>num[:2]
[1,2]
>>>num[2:]
[3,4,5]
>>>num[0:4:2]
[1,3]
- 相加
相加很好理解,就是两个序列进行拼接。
>>>num = [1,2,3,4,5]
>>>id = [7,8,9]
>>>num + id
>>>[1,2,3,4,5,7,8,9]
>>>surname = 'wang'
>>>name = 'jue'
>>>surname + name
'wangjue'
- 乘法
乘法表示一个数字n乘以一个序列会将原来的序列重复n次。这里面注意的是全部是引用,改变深层数据,后面的也会改变。
>>>num = [1,2,3]
>>>num * 2
[1,2,3,1,2,3]
>>>id = [[1,2,3]]*2
>>>id
[[1, 2, 3], [1, 2, 3]]
>>>name = 'wangjue' * 2
>>>'wangjuewangjue'
- 成员资格
所谓成员资格,就是此元素是否在该序列中。
>>>num = [1,2,3]
>>>1 in num
True
>>>'a' in num
False
- 长度、最大值、最小值
>>>num = [1,2,3]
>>>name = 'wangjue'
>>>len(num)
3
>>>max(num)
3
>>>len(name)
7
>>>min(name) # ASCII编码排序
'a'
1、列表
列表是一种序列,可以进行以上序列的所有操作之外,还可以进行以下操作。
- 基本操作
基本操作包括元素赋值、删除元素、分片赋值,另外通过list()可以生成列表。
>>>num = [1,2,3]
>>>num[0] = 10
>>>num
[10,2,3]
>>>del num[0]
>>>num
[2,3]
>>>num[0:1] = [0,1,2,3]
>>>num
[0,1,2,3,3]
>>>list('wangjue') #字符串转换为列表
['w', 'a', 'n', 'g', 'j', 'u', 'e']
>>>list((1,2,3)) #元组转化为列表
[1,2,3]
- 追加append
在列表后面追加元素。
>>>num = [1,2,3]
>>>num.append(1)
>>>num
[1,2,3,1]
- count
统计某个元素在列表中出现的次数.
>>>num = [1,2,3,1]
>>>num.count(1)
2
- extend
在列表后面追加另一个序列的多个值。
>>>num = [1,2,3]
>>>num.extend(num)
>>>num
[1,2,3,1,2,3]
- index
在列表中找到指定元素的第一个位置,找不到报错。
>>>num = [1,2,3]
>>>num.index(2)
1
>>> num.index(9)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: 9 is not in list
- insert
将元素插入到指定的位置,后面的元素依次后移。
>>>num = [1,2,3]
>>>num.insert(2,10)
>>>num.insert(2,[1,2])
>>>num
[1, 2, [1, 2], 10, 3]
- pop
pop方法是移除列表的一个元素,默认移除最后一个,并且返回移除元素的值。
>>>num = [1,2,3]
>>>num.pop()
3
>>>num
[1,2]
- remove
remove用于移除指定的元素的第一个。
>>>num = [1,2,3,1]
>>>num.remove(1)
>>>num
[2,3,1]
- reverse
reverse是将列表的元素倒序。
>>>num = [1,2,3]
>>>num.reverse()
>>>num
[3,2,1]
- sort
sort是对列表进行排序,注意这里排序是inplace操作,即在原来是列表上进行修改。(使用的是Timsort算法),默认升序。
>>>num = [3,4,2,1,5]
>>>num.sort()
>>>num
[1,2,3,4,5]
>>>num.sort(reverse=True)
>>>num
[5,4,3,2,1]
注意:列表中的max()、min()函数是针对元素的,也就是按照元素中的数字、依次排序(如果是单个元素直接排序,如果元素是列表则按照列表中的元素第一个排序,如果第一个相同则比较第二个)。比如:
>>>num = [[12],[1,2],[10,24],[13,10],[13]]
>>>max(num)
[13, 10]
>>>num
[[12], [1, 2], [10, 24], [13, 10], [13]]
>>>num.sort()
>>>num
[[1, 2], [10, 24], [12], [13], [13, 10]]
>>>max(num)
[13,10]
介绍粗略,详细可以看这个。
2、元组
元组也是一种序列,但是不能修改,一般通过(),元素之间用逗号分隔开,不加括弧时,自动生成元组。另外,用tuple可以将序列转化为列表。
>>>1,2,3
(1,2,3)
>>>(1,2,3)
(1,2,3)
>>>tuple([1,2,3])
(1,2,3)
其他操作如索引、分片、最大值、最小值、计数、index(查找指定元素的第一个位置)、in(查找是否包含某元素)、相加、相乘等操作与列表类似。由于元组不能改变,因此不支持修改、插入、排序、倒序、等操作。
介绍粗略,详情可以看看这个。
3、字符串/Unicode字符串
字符串也是一种序列,如索引、分片、乘法、判断成员资格、求长度、最小值、最大值同列表操作类似。但是不能对单个元素进行删除(del)、修改(赋值)操作。下面介绍字符串的一些操作。
- 字符串格式化
字符串格式化是指使用字符串格式化操作符,即用%实现。
>>>words = "hello I'm %s"
>>>name = 'wangjue'
>>>words % name
"hello I'm wangjue"
>>>words = "Pi is %.3f"
>>>pi = 3.1415926
>>>words % pi
'Pi is 3.142'
- find
find可以在一个较长的字符串中查找子串,并返回子串的左端索引,没有找到返回-1。(列表、元组中in只能查找单个字符,并且返回True/False)
str.find(str, beg=0, end=len(string)),str是查找的字符串,beg是开题,end是结尾,默认0开始到最后
>>>name = 'wangjue'
>>>name.find('jue')
4
- join
join是将一个字符/字符串序列拼接成字符串
>>>num = ['1','2','3']
>>>"-".join(num)
"1-2-3"
- lower/upper
lower/iupper返回字符串的小写/大写,原字符串不变,如果字符没有大小写形式,则返回原字符。
>>> name = 'wangjue2019AAA'
>>> name.lower()
'wangjue2019aaa'
>>> name.upper()
'WANGJUE2019AAA'
- replace
replace是替换的意思,可以替换字符、字符串,返回为替换之后的结果,原来的结果不变。
>>>name = 'wangjue'
>>>name.replace('jue','ll')
'wangll'
>>> name
'wangjue'
- split
split是将字符串以某一个字符/字符串进行分割开,返回新的列表,默认分隔符是空格。
>>>name = 'wa-ng---jue'
>>>name.split('-')
['wa', 'ng', '', '', 'jue']
>>>name.split('--')
['wa-ng', '-jue']
>>>name = 'wang jue'
>>>name.split()
['wang', 'jue']
- strip
strip方法除去某个字符/字符串之后,返回,默认去除字符串头尾的空格,原字符串不变。
>>>name = ' wang *jue '
>>>name.strip()
'wang *jue'
>>>name.strip('*')
' wang *jue '
三、映射
映射是指通过名字就能找到值,这种名字-值的方式就是一种映射,这里主要介绍字典这种数据结构。
字典
字典存储是是以键-值对的形式(key-val)进行数据存储,通过key(主要key是唯一的)可以索引到val,相比序列中只能通过下标来说,提高了访问效率。简单来说,字典是通过hash函数将key转化成一个hash值(可能会存在hash冲突,也就是不同的key转化成相同的hash值),将此hash值对数组最大长度进行取余获得存储的数组下标。为了避免hash冲突,python采用开放地址的方法实现,即此下标已经有数据,则对下标进行后移。这个分析的很好,可以学习哈!
- 字典的创建
>>>name_age = {'zhao':17,'qian':13,'sun':14}
>>>name_age
{'zhao': 17, 'qian': 13, 'sun': 14}
>>>dict([('zhao',17),('qian',13),('sun',14)])
{'zhao': 17, 'qian': 13, 'sun': 14}
- 基本操作
字典的基本操作包括len()返回字典长度;name[key]获得字典中的值;name[key]=val将val关联到key上,如果key不存在则创建;del name[key]删除;in判断是否包含key。 - clear
清除字典的所有项。
>>>name_age = {'zhao':13}
>>>name_age.clear()
>>>name_age
{}
- copy
字典中的copy是浅复制。浅复制和深复制的区别看这里。
>>>name_age = {'zhao':13}
>>>name2 = name_age.copy()
>>>name2
{'zhao':13}
- fromkeys
fromkeys是用给定的键构建新的字典,每个键对应的默认值是None。
>>>{}.fromkeys(['name','keys'])
{'name': None, 'keys': None}
>>>dict.fromkeys(['name','keys'])
{'name': None, 'keys': None}
- get
get方法是一个更宽松访问字典项的方法,如果可以name[key]的形式访问时,如果没有改key则会报错,但是get方法会返回None,另外可以设置检索不到时的返回值。
>>>name = {1:1,2:2}
>>>>print(name.get(3))
None
>>>print(name.get(3,'wang'))
wang
- items和iteritems
items和iteritems都是将字典中所有的项返回的。items是将所有的键值对以列表的形式返回,但是iteritems是返回一个迭代器(python2)。关于迭代器,可以看看这个。
>>>name = {1:1,2:2,3:3}
dict_items([(1, 1), (2, 2), (3, 3)])
- keys和iterkeys
keys和iterkeys都是返回字典中的所有键,keys返回列表,iterkeys返回迭代器(python2)。
>>>name = {1:1,2:2,3:3}
>>>name.keys()
dict_keys([1, 2, 3])
- values和itervalues
values和itervalues返回字典的所有val,values返回列表,itervalues返回迭代器(python2)。
>>> name
{1: 1, 2: 2, 3: 3, 4: 4}
>>> name.values()
dict_values([1, 2, 3, 4])
- pop
pop是移除字典的某个键,同时返回该键的值。
>>>name = {1:1,2:2,3:3}
>>>name.pop(1)
1
>>>name
{2:2,3:3}
- popitem
popitem是弹出字典的最后一个元素,但是由于字典是无序的,所以弹出的是随机项。
>>>name = {2: 2, 0: 1, 'a': 2, 'a0': 3}
>>>name.popitem()
('a0', 3)
>>>name
{2: 2, 0: 1, 'a': 2}
- setdefault
setgdefault是插入key的,如果不存在key,可以设置val,如果存在,则不会更新val,并且返回val。
>>>name = {1:1,2:2,3:3}
>>>name.setdefault(4,4)
4
>>>name
{1: 1, 2: 2, 3: 3, 4: 4}
>>>name.setdefault(4,3)
4
>>>name
{1: 1, 2: 2, 3: 3, 4: 4}
- update
用一个字典更新另一个字典。
>>>name = {1:2,3:4}
>>>name2 = {4:4,1:1,3:3}
>>>name.update(name2)
>>>name
{1: 1, 3: 3, 4: 4}
关于字典的介绍就这么多了,详细请看这个。
四、集合
集合和我们数学意义上的集合类似,元素唯一、无序、有交并补等操作。
- 创建
可以使用{}和set()创建集合,创建空集合必须用set(),{}会创建字典。
>>>name=set()
>>>name
set()
>>>name=set([1,2,3,3])
>>>name
{1,2,3}
>>>name = {1,2,3,4,3,2,1}
>>>name
{1,2,3,4}
- 交并补
交并补与数学含义交并补一致。
>>>name = {1,2,3,4,5}
>>>name2 = {3,4,5,6,7}
>>>name - name2
{1, 2}
>>>name | name2
{1, 2, 3, 4, 5, 6, 7}
>>>name & name2
{3, 4, 5}
>>>name ^ name2
{1, 2, 6, 7}
- 其他操作
集合还有其他的操作,添加(add)、更新(update)、移除(remove不存在报错、pop随机移除、discard不存在不报错)、长度(len)、清空(clear)、存在判断(in)。由于这些内容以上基本都介绍过了,不在赘述。
详情参考。
未完待续
完结撒花!若有纰漏或者错误,还请各位多多指教。谢谢~
参考:https://www.python.org/
https://www.runoob.com/python3/python3-intro.html
《python基础教程(第2版 修订版)》Magnus Lie Hetland著,司维 曾军崴 译,人民邮电出版社