知识前导总结:
四种数据结构:list、链表、queue、stack
list、链表、queue、stack栈的区别:
list:列表是内存分配的一段连续的内存空间,同时是可索引、可迭代、可改变的
- 列表也可以是一个元素
- 列表中的个体称为元素
- 元素可以是任意对象(字符串,数值,对象,列表)
- 线性的数据结构,
- 使用[]表示
- 列表是可变的
链表:在内存中分配不是一段连续的内存空间。数据元素的逻辑顺序是通过链表中的指针链接次序实现的,链表由一系列结点组成(链表中的每个元素都是一个结点),结点可以在运行时动态生成。
- 链表在插入的时候可以达到O(1)时间
- 查找一个结点或者访问特定编号的节点需要O(n)时间
队列(queue):队列是一种特殊的线性表,操作受限的线性表
- 只允许在表的前端front进行删除操作
- 而在表的后端rear进行插入操作
- 进行插入操作的端称为队尾,进行删除操作的端称为队首
- 插入时称为入队,删除时称为出队
stack(栈):后进先出
list()中嵌套列表相乘:涉及到内存的存放;
例如:
Number = [1, [2, 3, 4], 5]
Number_Test = Number * 2
Number[1][0] = 20
Number_Test = [1, [20, 3, 4], 5, 1, [20, 3, 4], 5]
涉及到的知识:
1,列表中的元素在内存中存储的是元素的内存地址号码,当我们乘2次时,只是把引用这个内存地址的指针复制2存放,指针指向的都是同一个地方。
2,列表时内存分配的一段内存空间,当它引用的时候,引用的时内存地址!单类型直接存放,如列表这种空间类型引用的是另外一个列表的内存地址。
1,list():列表
1,列表是一个元素访问O(1)
2,列表本身也是一个可迭代对象
3,列表索引可以从左到右,从0开始,或者从右到左,从-1开始
4,正负索引不能超界
方法:
1,name = list():list()中必须是一个可迭代对象,# num = list(range(5))
2,list[index]:索引访问,index就是索引号。 # num[5]
3,array.index(value, [start, [stop]]):
1,通过value值,从指定区间查找列表内的元素是否匹配。
2,匹配到第一个就返回索引值
3,匹配不到就抛出异常ValueError
4,使用start和stop,负方向必须是从最小到最大
#num.index(2),#num.index(2, -4, -1)
4,array.count():查找元素个数。# num.count(2)
5,array[index] = value:元素修改,# array[2] = 3
6,array.append():元素增加,在列表尾部追加。# num.append(3)
7,array.insert(index, value):元素插入,允许超界。# num.insert(3, 2)
8,array.extend(iteratable):元素扩展,iteratable为可迭代对象。 # num.extend(range(5))
9,array.remove(value):元素删除,从左到右查找第一个匹配value的值,移除该元素,返回None。# num.remove(2)
10,array.pop(index):不指定索引,从列表尾部弹出一个元素O(1)。指定索引,就从索引处弹出一个元素,索引超界抛出IndexError
11,array.clear():清除列表所有数据。返回值是None
12,array.reverse():列表元素反转。 # num.reverse()
13,reversed(seq):内建函数反转
1,在内存中创建一个可迭代对象,什么时候使用什么时候迭代,不影响原数据
2,返回一个迭代器,可以使用for来打印这个迭代器中的数据!
#reversed(num), for i in reversed(num): print(i)
14,+:列表相加:如果不赋值给一个新的变量,则返回一个新的列表输出到屏幕上。 # num + six
15,*:列表复制:如果不赋值给一个新的变量,则返回一个新的列表输出到屏幕上。 # num * 2
16,len():输出对象长度,时间复杂度是O(1)。 # len(num)
2,tuple():元组
1,元组是一个可索引、可迭代、线性有序的不可改变
2,元组用()小括号表示
3,元组创建如果在小括号中,必须给出逗号,否则不是元组
定义:
tuple()或者t = (1,) #必须给出逗号,否则创建的不是一个元组
注意:因小括号给表达式优先级使用,所以必须给逗号才能创建元组
元组中嵌套列表,列表是可以修改的!
# t1 = ([1, 2, 3],) * 5
# t1[0][1] = 3
# ([1, 3, 3], [1, 3, 3], [1, 3, 3], [1, 3, 3], [1, 3, 3])
元组操作:
1,count(value):统计value出现的次数
2,index(index):返回index位置的value值
3,str():字符串
1,字符串是由一个个字符组成的有序的序列,是字符的集合,可迭代的,可索引
2,使用单引号、双引号、三引号引住的字符序列
3,字符串中的字符的类型是str()类型
4,字符串是不可变的对象,不能修改
5,Python3开始,字符串就是Unicode(UTF-8)类型
字符串方法:
1,name = 'abc':字符串赋值
2,前缀r和R:# s1 = r'hello \n word' 返回'hello \\n world'
3,三引号:三引号中可以自由使用单引号和双引号,并不会报错
# s1 = """select * from user where name = 'tom'"""
4,array[index]:字符串也是通过索引来访问,# s1[3]
5,str.join(iterable):
1,将可迭代对象连接起来,使用str作为分隔符,返回一个新的字符粗 # ','.join(s1)
2,被join分隔的必须是字符串类型,如果不是需要用map函数转换 # s2 = [1, [20, 3, 4], 5, 1, [20, 3, 4], 5] # ','.join(map(str, s2))
3,如果不是字符串类型,会引发类型错误TypeError
6,+:字符串连接并不是修改了字符串,而是创建了一个新的字符串
7,array.split(seq=None, maxsplit=1):字符串分割,返回的是一个列表
1,从左到右,seq指定分割字符串,缺省的情况下是(空白字符串)
2,maxsplit指定分割的次数,-1表示遍历整个字符串
3,maxsplit切几次,并不是按照我们的固定思维平均切,而是按照分隔符一个一个切
#s1 = 'hello word' #s1.split() = ['hello', 'word']
8,array.rsplit(seq=None, maxsplit=-1):字符串分割,返回的是一个列表
1,从右到左,seq指定分割字符串,缺省的情况下是(空白字符串)
2,maxsplit指定分割的次数,-1表示遍历整个字符串
3,maxsplit切几次,并不是按照我们的固定思维平均切,而是按照分隔符一个一个切
#s1 = 'hello word' #s1.rsplit() = ['hello', 'word']
9,array.splitlines(keepends=False):
1,按照行来切分字符串
2,keepends指的是是否保留分隔符
3,行分隔符:\n、\r、\r\n。前面3种类型只算一个行分隔符。\r\r算2个
#'heelo word\n hello'.splitlines(keepends=True)
10,array.partition(sep):
1,从左到右,遇到分隔符就把字符串分割成两部分,返回头、分隔符、尾三部分
2,没有找到分隔符,就返回头、2个元素的三元组
3,seq必须指定分割字符串
#'six = 32'.partition('=') 返回('six ', '=', ' 32')
#'hello word'.partition('fefe') 返回('hello word', '', '')
11,array.upper():小写字母转换成大写 # 'abc'.upper() 返回'ABC'
12,array.lower():大写字母转换成小写 # 'ABC'.lower() 返回'abc'
13,array.swapcase():小写转大写,大写转小写 # 'hello WORD'.swapcase() 返回'HELLO word'
14,array.title():字符串排版,单词首字母大写 # 'hello word'.title() 返回'Hello Word'
15,array.capitalize():首个单词首字母大写 #'hello word'.capitalize() 返回'Hello word'
16,array.center(width[,fillbyte]):打印宽度,填充的字符 # 'hello word'.center(20, '*') 返回'*****hello word*****'
17,array.zfill(width):打印宽度,右靠齐,左边用0填充 # 'hello word'.zfill(20) 返回'0000000000hello word'
18,array.ljust(width,[fillbyte]):打印宽度,左对齐 # 'hello word'.ljust(20, '*') 返回'hello word**********'
19,array.rjust(width,[fillbyte]):打印宽度,右对齐 # 'hello word'.rjust(20, '*') 返回'**********hello word'
20,array.replace(old, new[,count]):字符串修改,并不是修改了字符串,而是返回了一个新的字符串
#'www.baidu.com'.replace('w', ' ') 返回' .baidu.com'
21,array.strip([chars]):去除字符串两端指定的字符串集,匹配给出的字符串;如果不指定默认去除两端的空白字符串。# 'www.baidu.com'.strip('w') 返回'.baidu.com'
22,array.lstrip([chars]):从左边去除 # ' www.baidu.com '.lstrip() 返回'www.baidu.com '
22,array.rstrip([chars]):从右边去除 # ' www.baidu.com '.rstrip() 返回' www.baidu.com'
23,array.find(sub[,start[,end]]):从左到右查找sub,找到返回索引,没有找到返回-1
24,array.rfind(sub[,start[,end]]):从右到右查找sub,找到返回索引,没有找到返回-1
25,array.index(sub[,start,[end]]):从左到右,查找sub,找到返回索引,没有找到抛出索引异常
26,array.rindex(sub[,start,[end]]):从右到左,查找sub,找到返回索引,没有找到抛出索引异常
27,array.count(sub[,start[,end]]):从左到右,统计sub的个数
字符串判断:
1,array.endswith(suffix[,start[,end]]):在指定的区间,字符串是否是suffix的结尾 #'www.baidu.com'.endswith('com') 返回True
2,array.startswith(suffix[,start[,end]]):在指定的区间,字符串是否是suffix的开头 #'www.baidu.com'.startswith('ww') 返回True
3,array.isalnum():判断是否是字母和数字组成 # 'www123'.isalnum()
4,array.isalpha():判断是否是大写字母和小写字母 # 'wwwWW'.isalpha()
5,array.isdecimal():判断是否是十进制数字 # '123'.isdecimal()
6,array.isdigit():判断是否是数字 #
7,array.isidentifier():判断是否字母和下划线开头,其他都是字母、数字、下划线
8,array.islower():判断是否都是小写字母
9,array.isupper():判断是否是大写字母
10,array.isspace():判断是否只包含空白字符
4,bytes:字节
1,不可变的字节序列
2,bytes是字节组成的有序的序列
3,使用b前缀定义,只允许基本ASCII使用字符形式b'abc9'
字符串与bytes的关系:
1,字符串是(字符)组成的有序序列,[字符]可以使用编码(Unicode)来翻译
2,bytes是字节的序列,而str是Unicode的序列
3,str使用encode方法转化为bytes
4,bytes通过decode转换为str
5,bytes()的输出还是bytes()
str转化为bytes:
codecs.encode(obj, encoding='utf-8', errors='strict')
#s1 = '中国' #s1.encode() 返回b'\xe4\xb8\xad\xe5\x9b\xbd'
bytes转化为str:
codecs.decode(obj, encoding='utf-8', errors='strict')
#b'\xe4\xb8\xad\xe5\x9b\xbd'.decode() 返回'中国'
bytes()定义:
1,bytes():空字节
2,bytes(int):指定字节的bytes
3,bytes(iteratable_of_ints):可迭代对象,必须是int()整数类型
4,bytes(string, encoding[, errors]):等价于string.encode()
5,bytes(bytes_or_buffer):从一个字节序列或者buffer复制出一个新的不可变的bytes对象
操作方法:
1,bytes.replace(old, new[, count]):替换字节 # b'abcdef'.replace(b'f', b'ef') 返回b'abcdeef'
2,bytes.find(sub[, start[, end]]):查找字节 # b'abcdef'.find(b'f') 返回 5
3,bytes.fromhex(string):把十六进制的数值转换成字节 # bytes.fromhex('6162') 返回b'ab'
4,hex(x):把x转换为十六进制表达 # hex(16) 返回'0x10' ## 'abc'.encode().hex() 返回'616263'
5,b'abcd'[2]:返回的是ASCII表中对应的十进制数值 # b'abc'[2] 返回99
5,bytearray():
1,bytearray()是可变的
2,是由字节组成的有序的序列(数组)
bytearray()定义:
class bytearray([source[, encoding[, errors]]])
1,bytearray():空bytearray()
2,bytearray(int):指定字节的bytearray,被0填充 # bytearray(1) 返回bytearray(b'\x00')
3,bytearray(iterable_of_ints):返回一个新的bytearray[0, 255]的int组成的可迭代对象!
#bytearray(range(5))
#bytearray(b'\x00\x01\x02\x03\x04')
#for i in bytearray(b'\x00\x01\x02\x03\x04'): print(i)
4,bytearray(string, encoding[, errors]):返回一个新的bytearray,近似string.encode(),返回对象可变
5,bytearray(bytes_or_buffer):从一个字节序列或者buffer复制出一个新的可变的bytearray对象
**重点:b前缀定义的类型是bytes()类型,不要搞乱了!**
操作方法:
1,bytearray.replace():替换字节 #bytearray(b'abcdef').replace(b'f', b'ef') 返回bytearray(b'abcdeef')
2,bytearray.find(sub[, start[, end]]):查找字节
3,classmethod fromhex(string):string必须是2个字符的十六进制的形式 # bytearray.fromhex('616263') 返回bytearray(b'abc')
4,bytearray('abc'.encode())
5,bytearray(b'abcdef')[2]:返回对应ASCII表中对应的十进制数值,并且是int类型
因为bytearray是可变的,所以有类似列表的一些操作方法!
1,append(int):尾部追加一个元素 # bytearray(b'') b.append(0) 返回bytearray(b'\x00')
2,insert(index, int):在指定索引位置插入元素 # b.insert(2, 97) 返回bytearray(b'\x00a')
3,extend(iteratable_of_ints):将一个可迭代的整数集合追加到当前bytearray
4,pop(index):可以指定索引移除元素,不指定默认从尾部移除
5,remove(value):从左到右,找到第一个vlaue移除,找不到抛出Value errors
6,clear():清空bytearray
7,reverse():翻转bytearray,就地修改
6,set():集合
哈希:一般翻译做“散列”,就是把任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列!
dict和set实现原理,都是将实际的值放到list中,唯一不同的在于hash函数操作的对象,对于dict,hash函数操作的是其key,而对于set是直接操作它的元素,
重点:set的成员运算效率是O(1)的,因为set中
1,set()是可变的
2,set()是无序的不可索引,但是可以迭代
3,set()是元素不重复的集合
4,set()中的元素必须是可hash的
可hash的:
元组、int、str、bytes、
不可hash的:
list、set、bytearray
set()定义:
set():创建一个空的集合对象
set(iteratable):中间是可以迭代的对象
set:集合是非线性的结构
操作方法:
1,add(elem):增加一个元素到set中 #s1 = set() s1.add(9)
2,update(*others):合并其他元素,参数other必须是可迭代对象,就地修改。 #s1.update(range(10))
3,remove(elem):从set中移除一个元素:set中的元素都是hash之后存放,所以会抛KeyError
1,元素不存在,抛出异常:Key Error异常
4,discard(elem):从set中移除一个元素,元素不存在,则什么都不做
5,pop():移除并返回任意的元素,因为set是一个无序的集合,空集合返回KeyError异常
6,clear():移除所有元素
7,dict():字典
1,字典是一个key-value键值对的数据的集合
2,字典是可变的、无序的、并且key是唯一的不重复的
字典的一些使用注意:
1,在迭代字典的keys、values、items三种方法的时候修改字典的大小,也就是增加或者删除字典中的key-value,但是可以修改value的值
2,字典的key必须是一个可hash的类型
字典的方法:
defaultdict:from collections import defaultdict
1,第一个参数时default_factory,缺省是None,它提供一个初始化函数,当key不存在的时候,会调用这个工厂函数来生成key对应的value!
from collections import defaultdict
import random
NumDict = defaultdict(list)
for k in 'abcdef':
for i in range(random.randint(1, 5)):
NumDict[k].append(i)
print(NumDict)
OrderedDict:from collections import OrderedDict
1,key并不是按照加入的顺序排列,可以使用OrderedDict记录顺序
2,有序字典可以记录元素插入的顺序,打印的时候也是按照这个顺序输出打印
from collections import OrderedDict
import random
NumDict = {'a':1, 'b':2, 'c':3}
print(NumDict)
keys = list(NumDict.keys())
random.shuffle(keys)
odNumDict = OrderedDict()
for key in keys:
odNumDict[key] = NumDict[key]
print(odNumDict)
print(odNumDict.keys())
dict()定义和初始化:
1,dict()或者d = {}
2,dict(**kwargs)使用name = value对初始化一个字典
3,dict(iterable, **kwargs)使用可迭代对象和name=value对构造字典,不过iterable的元素必须是一个二元结构
# numdict = dict(((1, 'a'), (2, 'b')))
4,dict(mapping, **kwarg):使用一个字典构建另一个字典
# numdict = {'a':10, 'b':20, 'c':None, 'd':[1, 2, 3]}
5,类方法dict.fromkeys(iterable, value):
# numdict = dict.fromkeys(range(5))
# numdict = dict.fromkeys(range(5), 0)
字典元素的访问:
1,d[key]:返回key对应的值value,key不存在抛出KeyError异常
2,get(key[,default]):返回key对应的值value,key不存在返回缺省值default,如果没有设置缺省值就返回None
3,setdefault(key[,default]):返回key对应的值value,key不存在,添加key-value,value为default,并返回default;如果没有default没有设置,缺省为None
字典增加和修改:
1,d[key] = value:将key对应的值修改为value,key不存在添加新的key-value到字典中
2,update([other]):使用另一个字典的key-value更新本字典、key不存在就添加、key存在覆盖已经存在的key对应的值,而且是就地修改!
# d.update(red=1)
# d.update(a) a为另外一个字典
# d.update((('red', 2),)) #一个二元组
# d.update({'red':3})
字典的删除:
1,pop(key[,default]):key存在,移除它,并返回它的value,key不存在,返回缺省的default;default未设置,key不存在则抛出KeyError异常
2,popitem():移除并返回一个任意的key-value(key和value都返回,不同于pop),字典为empyt空时,抛出KeyError异常
3,clear():清空字典
4,del:删除字典中的元素的引用
# del d['f']
字典的遍历:
Python3中:keys、values、items方法返回一个类似一个生成器的可迭代对象,不会把函数的返回结果复制到内存中。
Dictionary view对象
字典的entry的动态的视图、字典变化,视图将反映出这些变化
# type(d.keys())、type(d.values())、type(d.items()) 返回都是dict_keys,dict_values,dict_items,一个类似迭代器
# d.keys() 和 d.values()只会返回对应的值
# d.items()返回的时key和value组成的元组,可以通过解构重新赋值给其他变量
id(d.keys())
2483256383192
------------
id(d.items())
2483256383192
------------
id(d.values())
2483258591128
------------
id(d)
2483267732032
Python2中,上面的方法会返回一个新的列表,占据新的内存空间,所以Python2建议使用iterkyes、itervalues、iteritems版本,返回一个迭代器,而不是一个copy!
字典中sorted排序:
1,按照items排序,把二元组强制转化为str,在依次比较
str(('a',0))
"('a', 0)"
str((1,100))
'(1, 100)'
('a', 0) (1, 100):括号相同,比较引号与1哪个大!
#sorted({'c':1, 'b':200, 'd':300, 1:1000}.items(), key=str)
#[('b', 200), ('c', 1), ('d', 300), (1, 1000)]
2,先转化为str,比较完之后,在以原来的类型显示
#sorted({'c':1, 'b':200, 'd':300, 1:1000}, key=str)
#[1, 'b', 'c', 'd']
8,集合:
定义:
1,全集:所有元素的集合
2,子集subset和超集superset
一个集合A所有元素都在另一个集合B内,A是B的子集,B是A的超集
3,真子集和真超集
A是B的子集,且A不等于B,A就是B的真子集,B是A的真超集
4,并集:多个集合合并的集合
5,交集:多个集合的公共集合
6,差集:集合中除去和其他集合的交集
集合操作运算:
1,并集:
解释:将2个集合的所有元素合并到一起,组成的集合
1,union(*others):返回多个集合合并后的新集合
2,|:运算符重载等同于union
3,update(*other):合并多个集合,就地修改
4,|=:等同于update(*other)
In [415]: T_test1.union(T_test2)
Out[415]: {0, 1, 2, 3, 4, 'a', 'b', 'c', 'd', 'e'}
2,交集:
解释:集合A和集合B,由所有属于A且属于B的元素组成的集合
1,intersection(*others):返回多个集合的交集
2,&:等同与intersection
3,intersection_update(*other):多个集合的交集,就地修改
4,&=:等同于intersection_update(*other)
In [416]: T_test1.intersection(T_test2)
Out[416]: set()
3,差集:
解释:集合A和集合B,由所有属于A且不属于B的元素组成的集合
1,difference(*others):返回多个集合的差集
2,-:等同于difference
3,difference_update(*others):返回多个集合的差集并就地修改
4,-=:等同于difference_update
In [417]: T_test1.difference(T_test2)
Out[417]: {0, 1, 2, 3, 4}
In [418]: T_test2.difference(T_test1)
Out[418]: {'a', 'b', 'c', 'd', 'e'}
4,对称差集:
解释:集合A和集合B,由所有不属于A和B的交集元素组成的集合
1,symmetric_differece(other):返回和另一个集合的差集
2,^:等同于symmetric_differece
3,symmetric_differece_update(other):返回和另一个集合的差集并就地修改
4,^=:等同于symmetric_differece_update
In [419]: T_test1.symmetric_difference(T_test2)
Out[419]: {0, 1, 2, 3, 4, 'a', 'b', 'c', 'd', 'e'}
集合元素:
1,issubset(other)、<=
判断当前集合是否是另一个集合的子集
2,set1 < set2
判断set1是否是set2的真子集
3,issuperset(other)、>=
判断当前集合是否是other的超集
4,set1 > set2
判断set1是否是set的真超集
5,isdisjoint(other)
当前集合和另一个集合没有交集,没有交集,返回True