大纲
-
容器切片
-
list/tuple
dict
set
-
- 切片
- 列表推导
- 生成器
- 迭代器
容器
list 列表
序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。
列表的数据项不需要具有相同的类型
tuple 元组(只读列表)
像C++的const
dict 字典
字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中。
set 集合
是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交), difference(差)和sysmmetric difference(对称差集)等数学运算。
容器 - list/tuple基本操作
li = [1, 2, 3, '456', [1, 2, 3], {1: 'one', 2: 'two'}] print(type(list)) print(type(li))
<class 'type'>
<class 'list'>
# 元素访问 print(li[0]) print(li[-1]) # li[len(li) - 1] print(li[-2]) # li[len(li) - 2]
# 查找元素位置 print(li.index('456')) print(li.index([1, 2, 3])) #print(li.index(-1))
创建
添加元素(list only):append, extend
# 添加元素 l_a= [1, 2, 3] l_a.append(4) l_a.append(5) l_b = [6, 7, 8] l_a.extend(l_b) # 试用下append什么结果 print(l_a) def my_extend(li, n_li): for i in n_li: li.append(li) # 其实就是把要添加的数组展开了
删除元素(list only):del, pop
根据索引读写(tuple只读)
判断容器是否为空
# 判断容器是否为空 l_a = [] if not l_a: print('Empty') if l_a is None: print('Empty')# 没有分配内存,不显示 # None和not 不是一回事 if len(l_a) == 0: print('Empty')
字符串转换
容器元素数量
遍历
# 遍历 for i in li: print(i)# 直接遍历 for i in range(len(li)): print(li[i])# 根据索引去访问每个元素
容器 - dict基本操作
初始化
访问
添加元素
修改元素
删除元素
判断key是否存在
判断容器是否为空
容器元素数量
遍历
# 无序的key:value数据结构 d = {'a': 1, 'b': 2, 1: 'one', 2: 'two', 3:[1, 2, 3]} print(type(dict)) print(type(d)) print(d) # 访问元素 print(d['a']) print(d[1]) print(d[3]) # 判断元素是否存在 print('c' in d) print(3 in d) del(d['a'])# del(dict[key]) print(len(d))
#遍历 d = {'a': 1, 'b': 2, 1: 'one', 2: 'two', 3:[1, 2, 3]} for key in d: print(d[key]) print('.....') for key, value in d.items(): print(key, value) keys = d.keys() print(type(keys)) print(keys)
容器 - set基本操作
并/交/差集:|/union, &/intersection, -/difference
对称差集:^/symmetric_difference(不同时出现在2个集合中的项)
包含关系:>=/issuperset
添加元素
更新元素
删除元素
元素是否存在
容器元素数量
遍历
print(s_a.difference(s_b)) # 对称差(A | B) - (A & B) print(s_a ^ s_b) print(s_a.symmetric_difference(s_b)) # 修改元素 s_a.add('x') s_a.update([4, 5, 60, 70]) print(s_a) # 删除元素 必须知道元素的值 s_a.remove(70) print(s_a) # s_a.remove(100) # 遍历 print(len(s_a)) for i in s_a: print(i)
切片
存取序列(列表,元组,字符串)的任意一部分
格式:seq[开始索引:结束索引:步长]
默认值
负数索引
负数步长
# python的大杀器,怎么高效的切一个子数组,切片最大的用处 li = list(range(10)) print(li) # 切片 [start:end:steps] >= start & < end开区间 print(li[2:5]) # [2,3,4] print(li[:4]) # [0,1,2,3] print(li[5:]) # [5,6,7,8,9] print(li[0:10:3]) # [0,3,6,9] # 负数怎么处理? print(li[5:-2]) # [5,6,7] print(li[9:0:-1]) # [9,8,7,6,5,4,3,2,1] print(li[9::-1]) # [9,8,7,6,5,4,3,2,1,0] print(li[::-2]) # [9,7,5,3,1] #切片生成一个新的对象 print(li) # 还是保持原样 # 切片做快速反转 re_li = li[::-1] print(re_li)
列表推导
问题的提出
-
快速简单的生成一个列表
-
对原有的列表进行简单的转换
一维列表推导
二维列表推导以及注意事项
#生成数组对象的方法 li = list(range(10)) print(li) li = [] for i in range(20): if(i % 2) == 0: li.append(i) print(li) li = [0] * 10 print(li) # 列表推导 li = [i * 2 for i in range(10)] print(li) # 浅拷贝 li_2d = [[0] * 3] * 3# ×3代表把[[0]*3]引用了3次,每一列都是同一个对象 print(li_2d) li_2d[0][0] = 100 # 同时对这个3个都起了效果 print(li_2d) # [[100,0,0],[100,0,0],[100,0,0]] # 深拷贝 li_2d = [[0] * 3 for i in range(3)] li_2d[0][0] = 100 # 同时对这个3个都起了效果 print(li_2d) # [[100,0,0],[100,0,0],[100,0,0]] # 1维情况下做复制操作,多维使用的是引用 # python3字典和集合也支持列表推导操作,python2不支持 set = { x for x in range(10) if x % 2 == 0} print(set) dict = {x: x % 2 == 0 for x in range(10)} print(dict)
生成器
问题的提出
- 创建一个巨大的列表而仅仅需要访问其中少量几个元素
- 如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。
生成生成器:列表推导时用()替换[](关于yield的使用后面再讲)
遍历:next或者for循环
# 平方表 square_table = [] for i in range(10000): square_table.append(i * i) for i in range(10): print(square_table[i]) # 生成器,没有任何初始化开销的时间,把真正的计算推迟到你使用的时候 square_generator = (x * x for x in range(50000)) print(type(square_generator)) for i in range(10): print(next(square_generator)) # 在python3里range它返回一个新的对象,不是一个list, # 是一个<class 'range'>,定义了一个生成器 print(type(range(10))) # 协程,可控多线程 def fib(limit): n, a, b = 0, 0, 1 while n < limit: yield b a, b = b, a + b n += 1 return 'done' import traceback f = fib(5) print(next(f)) print(next(f)) print(next(f)) print(next(f)) print(next(f)) try: print(next(f)) except StopIteration: traceback.print_exc() for i in fib(5): print(i)
迭代器
问题的提出
- 可以直接作用于for循环的对象统称为可迭代对象:Iterable
- 可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator(表示一个惰性计算的序列)
集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
from collections import Iterable from collections import Iterator print(isinstance([1, 2, 3], Iterable))# 数组是可迭代的 print(isinstance([1, 2, 3], Iterator))# 但不是一个迭代器 print(isinstance({}, Iterable)) # True print(isinstance({}, Iterator)) # False print(isinstance(123, Iterable)) # False print(isinstance('abc', Iterable)) # True print(isinstance('abc', Iterator)) # False g = (x * x for x in range(3)) print(type(g)) print(isinstance(g, Iterable)) # True print(isinstance(g, Iterator)) # True for i in g: print(i) def fib(limit): n, a, b = 0, 0,1 while n < limit: yield b a, b = b, a+b n += 1 return 'done' f = fib(6) print(type(f)) print(isinstance(f, Iterable)) # True print(isinstance(f, Iterator)) # True for i in f: print(i)