目录
第四章 内置容器
4.1 容器的概述
1、容器的概念?为什么要学习容器?
容器:是一种可以存放多个数据(元素)的数据类型(引用数据类型 复合数据类型)
补充变量无法存储多个或者大量的数据的缺陷
2、python中提供的容器:
列表
集合
元组
字典
4.2 列表 ------- list
线性表(常见的线性表-------- 数组 栈 队列 链表)------- 基于链表的数据结构去实现
python中是没有数组(特点:查询速度比较快(因为都是连续的)增删改的速度比较慢)
栈:先进后出 后进先出
队列:先进先出 后进后出
链表: 单项链表 和双向链表
python中的列表是基于链表(双向链表)实现的
定义列表的方式:
弱数据类型语言:ls = [1,2,3,4]
list() : ls = list() ls = list([1,2,3,4])
>>> ls = [1,2,3,4,5] >>> type(ls) <class 'list'> >>> ls1 = list() >>> type(ls1) <class 'list'> >>> ls1 [] >>> ls2 = list([1,2,3,4,5,6]) >>> type(ls2) <class 'list'> >>>
如何访问元素?
可以使用角标(下标 索引)进行访问,注意下标是从0开始
>>> ls [1, 2, 3, 4, 5] >>> ls[0] 1 >>> ls[2] 3 >>> ls[5] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range
如果下标超出了范围的话,会报错(抛出异常),可以通过下标去修改值,下标也可以为负数
>>> ls [1, 2, 3, 4, 5] >>> ls[3] = 7 >>> ls [1, 2, 3, 7, 5] >>> ls[-1] 5 >>> ls[-5] 1 >>> ls[-6] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range
如何去计算列表的长度?
全局函数 len(容器) ------ 返回的容器的长度
>>> help(len) Help on built-in function len in module builtins: len(obj, /) Return the number of items in a container. >>> ls [1, 2, 3, 7, 5] >>> len(ls) 5 >>> len(ls2) 6 >>> ls2 [1, 2, 3, 4, 5, 6] >>> ls [1, 2, 3, 7, 5] >>> ls1 [] >>> len(ls1) 0
如何遍历列表?????
>>> ls [1, 2, 3, 7, 5] >>> for i in ls: ... print(i) ... 1 2 3 7 5 ls = [1,2,3,4,5,6] index = 0 while index < len(ls): print(ls[index]) index += 1
常见的方法:
全局函数dir(模块) ------ 查看某个模块里面的方法
>>> dir(ls) [ 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] >>>
append ------ 向列表的尾部添加元素
>>> help(ls.append) Help on built-in function append: append(object, /) method of builtins.list instance Append object to the end of the list. >>> ls [1, 2, 3, 7, 5] >>> ls.append("4") >>> ls [1, 2, 3, 7, 5, '4'] >>> ls.append(4) >>> ls [1, 2, 3, 7, 5, '4', 4]
insert ---- 向列表指定的位置添加元素
>>> ls [1, 2, 3, 7, 5, '4', 4] >>> ls.insert(3,8) >>> ls [1, 2, 3, 8, 7, 5, '4', 4]
sort ---- 列表排序 (通常情况下只能排序int类型的元素 默认是升序 如果元素是字母的话,排序的时候是依据ASCII码的值进行排序,要注意的是列表里面的元素不能混合使用不然不能排序)
>>> ls1 = [2,3,1,7,6,4,8,9,5] >>> ls1 [2, 3, 1, 7, 6, 4, 8, 9, 5] >>> ls1.sort <built-in method sort of list object at 0x0000023A6C854800> >>> ls1.sort() >>> ls1 [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> ls = ["A","b","c","D","B","a"] >>> ls ['A', 'b', 'c', 'D', 'B', 'a'] >>> ls.sort() >>> ls ['A', 'B', 'D', 'a', 'b', 'c'] >>> ls = ["A","b","B",1,2,3,7,6,5,4] >>> ls ['A', 'b', 'B', 1, 2, 3, 7, 6, 5, 4] >>> type(ls) <class 'list'> >>> ls.sort() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: '<' not supported between instances of 'int' and 'str'
index ---- 查找的是元素第一次在列表中出现的位置,如果没有这个元素则会抛出异常(报错)
>>> ls ['A', 'B', 'b', 1, 2, 3, 7, 6, 5, 4, 1, 2, 2] >>> ls.index(1) 3 >>> ls.index(2) 4 >>> ls.index(8) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: 8 is not in list
reverse ------ 将元素的顺序进行翻转
>>> ls ['A', 'B', 'b', 1, 2, 3, 7, 6, 5, 4, 1, 2, 2] >>> ls.reverse() >>> ls [2, 2, 1, 4, 5, 6, 7, 3, 2, 1, 'b', 'B', 'A']
remove ----- 通过元素进行移除元素,如果元素不存在会抛出异常(报错)
>>> ls [2, 2, 1, 4, 5, 6, 7, 3, 2, 1, 'b', 'B', 'A'] >>> ls.remove(2) >>> ls [2, 1, 4, 5, 6, 7, 3, 2, 1, 'b', 'B', 'A'] >>> ls.remove(7) >>> ls [2, 1, 4, 5, 6, 3, 2, 1, 'b', 'B', 'A'] >>> ls.remove(8) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: list.remove(x): x not in list
count ----- 统计的是元素在列表中出现的次数
>>> ls [2, 1, 4, 5, 6, 3, 2, 1, 'b', 'B', 'A'] >>> ls.count(2) 2 >>> ls.count(5) 1 >>> ls.count(7) 0
clear ----- 清除元素
>>> ls1 [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> ls2 [1, 2, 3, 4, 5, 6] >>> ls1.clear() >>> ls1 [] >>> ls2.clear() >>> ls2 []
copy ----- 浅拷贝对象 不等价与= 指的是在堆内存中进行对象的拷贝
>>> ls [2, 1, 4, 5, 6, 3, 2, 1, 'b', 'B', 'A'] >>> ls.copy() [2, 1, 4, 5, 6, 3, 2, 1, 'b', 'B', 'A'] >>> ls1 [] >>> ls1 = ls.copy() >>> ls1 [2, 1, 4, 5, 6, 3, 2, 1, 'b', 'B', 'A']
extend ----- 合并列表
>>> ls1 [2, 1, 4, 5, 6, 3, 2, 1, 'b', 'B', 'A'] >>> ls [2, 1, 4, 5, 6, 3, 2, 1, 'b', 'B', 'A'] >>> ls.extend(ls1) >>> ls [2, 1, 4, 5, 6, 3, 2, 1, 'b', 'B', 'A', 2, 1, 4, 5, 6, 3, 2, 1, 'b', 'B', 'A']
pop ------ 删除列表中的最后一个元素,有返回值,返回值是删除的元素,那如果要删除指定位置的元素,可以通过pop(i),i指的是索引(下标 角标)
>>> ls [2, 1, 4, 5, 6, 3, 2, 1, 'b', 'B', 'A', 2, 1, 4, 5, 6, 3, 2, 1, 'b', 'B', 'A'] >>> ls.pop() 'A' >>> ls [2, 1, 4, 5, 6, 3, 2, 1, 'b', 'B', 'A', 2, 1, 4, 5, 6, 3, 2, 1, 'b', 'B'] >>> ls.pop() 'B' >>> ls [2, 1, 4, 5, 6, 3, 2, 1, 'b', 'B', 'A', 2, 1, 4, 5, 6, 3, 2, 1, 'b'] >>> ls.pop(2) 4 >>> ls [2, 1, 5, 6, 3, 2, 1, 'b', 'B', 'A', 2, 1, 4, 5, 6, 3, 2, 1, 'b']
补充:
1、可以通过索引修改元素的值
2、list里面的元素类型可以不同
3、list里面可以包含(存放)另一个list
>>> ls2 [] >>> ls2 = [1,2,3,4,[1,2,3,4,5,6,7],5,6,7] >>> ls2 [1, 2, 3, 4, [1, 2, 3, 4, 5, 6, 7], 5, 6, 7] >>> type(ls2) <class 'list'> >>> ls2[4] [1, 2, 3, 4, 5, 6, 7] >>> ls2[4][4] 5 >>> ls2[4][4] = 8 >>> ls2 [1, 2, 3, 4, [1, 2, 3, 4, 8, 6, 7], 5, 6, 7]
4.3 集合 ------- set(哈希结构)
定义集合的方式:
s = {1,2,3,4}
s = set() s = set({1,2,3,4,5})
>>> s = {1,2,3,4,5} >>> s {1, 2, 3, 4, 5} >>> type(s) <class 'set'> >>> s = set() >>> s set() >>> type(s) <class 'set'> >>> s = set({1,2,3,4,5,6,7}) >>> s {1, 2, 3, 4, 5, 6, 7} >>> type(s) <class 'set'>
集合的底层是哈希结构(hash)表去实现 ------- 集合是无序的、不能重复的,无序指的不是顺序的意思,涉及到hash的底层,不能重复的指的是元素是唯一的
s[0] ------ 不支持的 会报错
>>> s[0] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'set' object is not subscriptable >>> s = {1,2,3,1,2,3,1,2,3,1,2,3} >>> s {1, 2, 3} >>> s = {3,2,1,4,6,5,7} >>> s {1, 2, 3, 4, 5, 6, 7}
常见的方法:
>>> dir(s) [ 'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']
clear
copy
pop
remove
add ----- 添加元素,如果元素重复的话,不能添加,不会报错
>>> s {1, 2, 3, 4, 5, 6, 7} >>> s.add(8) >>> s {1, 2, 3, 4, 5, 6, 7, 8} >>> s.add(8) >>> s.add(8) >>> s.add(8) >>> s {1, 2, 3, 4, 5, 6, 7, 8}
difference ------- 差集
intersection ----- 交集
union -------- 并集
>>> s {1, 2, 3, 4, 5, 6, 7, 8} >>> s1 {1, 2, 3, 4, 5, 8, 9} >>> s.difference(s1) {6, 7} >>> s1.difference(s) {9} >>> s.intersection(s1) {1, 2, 3, 4, 5, 8} >>> s1.intersection(s) {1, 2, 3, 4, 5, 8} >>> s.union(s1) {1, 2, 3, 4, 5, 6, 7, 8, 9} >>> s {1, 2, 3, 4, 5, 6, 7, 8} >>> s1 {1, 2, 3, 4, 5, 8, 9}
update ----- 更新集合 合并集合
>>> s {1, 2, 3, 4, 5, 6, 7, 8} >>> s1 {1, 2, 3, 4, 5, 8, 9} >>> s.update(s1) >>> s {1, 2, 3, 4, 5, 6, 7, 8, 9}
discard ----- 移除元素,如果元素不存在的话,不会报错
>>> s {1, 2, 3, 4, 5, 6, 7, 8, 9} >>> s.discard(9) >>> s {1, 2, 3, 4, 5, 6, 7, 8} >>> s.discard(9) >>> s.discard(9) >>> s.discard(9) >>> s {1, 2, 3, 4, 5, 6, 7, 8}
4.4 元组 ----- tuple
元组是有序的 ------ 可以通过下标去获取元素,下标也可以是负数,但是不能修改元素
元组的特点:有序的、不可变类型(元组中元素一旦确定下来,就不能发生改变)
定义方式:
t = (1,2,3,4)
t = tuple() t = tuple((1,2,3,4))
>>> t = (1,2,3,4) >>> t (1, 2, 3, 4) >>> type(t) <class 'tuple'> >>> tt = tuple() >>> type(tt) <class 'tuple'> >>> tt () >>> ttt = tuple(1,2,3,4,5) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: tuple expected at most 1 argument, got 5 >>> ttt = tuple((1,2,3,4,5)) >>> ttt (1, 2, 3, 4, 5) >>> type(ttt) <class 'tuple'> >>> t (1, 2, 3, 4) >>> t[0] 1 >>> t[5] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: tuple index out of range >>> t[0] = 3 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment
常见的方法:
>>> dir(t) ['count', 'index']
count
index
元组是不可变类型(元组中元素一旦确定下来,就不能发生改变),但是元组中的元素可以是可变类型,那么元组就可变(可变指的是元组里面可变类型的元素是可变的,并不是元组本身发生改变)
>>> t = (1,2,3,[1,2,3,4,5],5,6) >>> t (1, 2, 3, [1, 2, 3, 4, 5], 5, 6) >>> type(t) <class 'tuple'> >>> t[2] = 4 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment >>> t[3][2] = 7 >>> t (1, 2, 3, [1, 2, 7, 4, 5], 5, 6)
面试题: a = (1) ------- type(a)的返回类型是什么?
>>> a = (1) >>> a 1 >>> type(a) <class 'int'> >>> a = ("a") >>> a 'a' >>> type(a) <class 'str'>
如何定义只有一个元素的元组?
>>> a = (1,) >>> a (1,) >>> type(a) <class 'tuple'>
4.5 字典 -------- dict
字典存储是一个键值对(key-value)形式存在的数据
定义字典的方式:
d = {"name":"zhangsan","age":18}
d = dict() d = dict({"name":"zhangsan","age":18})
>>> d = {"name":"张三","age":18,"gender":"男"} >>> d {'name': '张三', 'age': 18, 'gender': '男'} >>> type(d) <class 'dict'> >>> dd = dict() >>> type(dd) <class 'dict'> >>> dd {} >>> ddd = dict({'name': '张三', 'age': 18, 'gender': '男'}) >>> ddd {'name': '张三', 'age': 18, 'gender': '男'} >>> type(ddd) <class 'dict'>
如何访问字典中的值????
通过key来访问对应的value d["name"],如果没有会抛出异常
可以通过key来修改value 字典对象[key] = 新value
字典对象新[key] = 新value 来添加新的键值对
>>> d["name"] '张三' >>> d["age"] 18 >>> d["sex"] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'sex' >>> d["name"] = "lisi" >>> d {'name': 'lisi', 'age': 18, 'gender': '男'} >>> d["address"] = "重庆" >>> d {'name': 'lisi', 'age': 18, 'gender': '男', 'address': '重庆'}
常用的方法:
>>> dir(d) [ 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
clear
copy
get ------- 通过Key获取value,如果没有不会抛出异常,类似于字典对象[key]
>>> d {'name': 'lisi', 'age': 18, 'gender': '男', 'address': '重庆'} >>> d.get("name") 'lisi' >>> d.get("sge") >>> d.get("ahe") >>> d.get("age") 18
keys ----- 返回所有的键值
values ------ 返回所有的value
items ----- 返回所有的键值对
>>> d {'name': 'lisi', 'age': 18, 'gender': '男', 'address': '重庆'} >>> d.keys() dict_keys(['name', 'age', 'gender', 'address']) >>> d.values() dict_values(['lisi', 18, '男', '重庆']) >>> d.items() dict_items([('name', 'lisi'), ('age', 18), ('gender', '男'), ('address', '重庆')])
setdefault ------ 设置默认值,默认的value
>>> d.setdefault("class") >>> d {'name': 'lisi', 'age': 18, 'gender': '男', 'address': '重庆', 'class': None} >>> help(d.setdefault) Help on built-in function setdefault: setdefault(key, default=None, /) method of builtins.dict instance Insert key with a value of default if key is not in the dictionary. Return the value for key if key is in the dictionary, else default.
pop ------- 通过key来移除键值对,如果没有会抛出异常
popitem ----- 移除键值对(按照先进后出的顺序进行移除的),返回的是移除的键值对
>>> d {'name': 'lisi', 'age': 18, 'gender': '男', 'address': '重庆', 'class': None} >>> d.pop("class") >>> d {'name': 'lisi', 'age': 18, 'gender': '男', 'address': '重庆'} >>> d.pop("class") Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'class' >>> d.popitem() ('address', '重庆') >>> d.popitem() ('gender', '男')
如何遍历字典?
>>> for i in d: ... print(i,d.get(i)) ... name lisi age 18 >>> d {'name': 'lisi', 'age': 18} >>> for k in d: ... print(k,d.get(k)) ... name lisi age 18 >>> for k in d: ... print(k,d[k]) ... name lisi age 18 >>> for k in d.keys(): ... print(k,d[k]) ... name lisi age 18 >>> for k,v in d.items(): ... print(k,v) ... name lisi age 18
4.6 常见的排序
4.6.1 冒泡排序
#冒泡排序 list = [8,3,2,9,1,7,4,6,5] for i in range(0,len(list)-1): # 0 1 for j in range(0,len(list)-1-i): #(0,8) (0,7) if list[j] >= list[j+1]: list[j],list[j+1] = list[j+1],list[j] print(list)
4.6.2 选择排序
找的最小值
#选择排序 list = [8,3,2,9,1,7,4,6,5] for i in range(0,len(list)): for j in range(i+1,len(list)): if list[i] >= list[j]: list[i],list[j] = list[j],list[i] print(list)
4.6.3 插入排序
#插入排序 list = [8,3,2,9,1,7,4,6,5] for i in range(1,len(list)): for j in range(i,0,-1): if list[j] <= list[j-1]: list[j],list[j-1] = list[j-1],list[j] print(list)
4.6.4 计数排序
#计数排序 list = [7,3,2,1,9,8,1,2,4,3] #找最大值和最小值 max_num = list[0] min_num = list[0] for num in list: if num > max_num: max_num = num elif num < min_num: min_num = num # print(max_num) # print(min_num) #计算计数列表的长度 len_list1 = max_num - min_num + 1 #偏移量 offest = min_num #初始化计数列表 计数列表里面的元素全部为0 list1 = [0] * len_list1 # print(list1) #排序后的列表 list2 = [0] * len(list) #计数 for num in list: # [7,3,2,1,9,8,1,2,4,3] 7 # print(num) list1[num-offest] += 1 #list1[7-1] = list1[6] = 0 + 1 = 1 list1[3-1] = list1[2] = 0 +1 = 1 print(list1) #[2, 2, 2, 1, 0, 0, 1, 1, 1] #排序后 index = 0 for i in range(0,len_list1): # (0,9) 0 1 for j in range(0,list1[i]): #(0,list1[0])=(0,2) 0 1 (0,list1[1]) = (0,2) list2[index] = i + offest # list2[0] = 0 + 1= 1 list2[1] = 0 + 1 =1 index += 1 # index = 1 2 print(list2)
4.7 查找算法 ---- 二分查找
#二分查找 list = [1,2,3,4,5,6,7,8,9,10,11,12,13] n = 11 left = 0 right = len(list)-1 while left <= right: middle = (left + right) // 2 if n > list[middle]: left = middle + 1 elif n < list[middle]: right = middle -1 else: print("存在!!!") print(middle) break else: print("不存在!!!!")