06-03线性结构与切片
线性结构与切片
线性结构
- 列表、元组、字符串、bytes, bytearray
- 共同点:都是顺序存储, 顺序访问的, 都是可迭代对象, 都可以通过索引访问
线性结构特征
- 可迭代
- len获取长度
- 可以使用下标操作符通过索引访问
- 可以切片
例如:可迭代的表现形式
In [1]: for i in [1, 2, 3]:
...: print(i)
...:
1
2
3
In [2]: for i in (1, 2, 3):
...: print(i)
...:
1
2
3
In [4]: for c in 'i lve python':
...: print(c)
...:
i
l
v
e
p
y
t
h
o
n
函数enumerate
作用:接收一个可迭代对象,返回一个enumerate对象
作用(菜鸟教程):enumerate(sequence, [start=0]) 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
实例:
In [5]: enumerate([1, 2, 3]) # 接收一个可迭代对象,返回一个enumerate对象(这种语句都不知道讲什么鬼)
Out[5]: <enumerate at 0x7fc5a6fa2750>
In [6]: list(enumerate([1, 2, 3])) # 会得到一个列表
Out[6]: [(0, 1), (1, 2), (2, 3)]
>>>seasons = ['Spring', 'Summer', 'Fall', 'Winter']
>>> list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
>>> list(enumerate(seasons, start=1)) # 下标从 1 开始
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
enumerate的实现
In [8]: def enumerate(iterator): # 方式1
...: i = ()
...: for v in iterator:
...: yield i, v
...: i += 1
...:
In [9]: def enumerate(interator): # 方式2
...: ret = []
...: i = ()
...: for v in iterator:
...: ret.append((i, v))
...: i += 1
...: return ret
...:
方式1与方式2并不等效, 但是返回的效果是一样的。
iter函数
作用:将一个可迭代对象转换为一个迭代器
两种使用方式:
- iter(iterable) -> iterator
- iter(callable, sentinel) -> iterator # sentinel必须是一个可调用对象,当每次调用这个__next__()方法时,都会调用该对象。
In [10]: len(range(5)) # 可迭代对象都可以用len获取长度
Out[10]: 5
iter函数可以将一个可迭代对象转换为一个迭代器
next函数可以读取迭代器的下一个值
In [11]: next(iter(range(5))) # 一起使用的方式
Out[11]: 0
可迭代对象可以通过 iter 函数转换为迭代器
切片操作
- 操作对象:都可以通过索引访问的数据类型
- 操作方式:都是返回一个新的对象,不会对原有数据做更改
- lst[start:stop] 可以访问这个list一段, 从start开始, 到stop结束, 不包含stop,例如lst[3:7]
- 当start为0时可以省略
- 当stop为-0的时候可以省略
- lst[:]都省略的时候等效于copy
- 支持负数索引,负数索引实际上可以转换为len(lst) + index
- 超出范围不报错
- start超出索引范围:start = 0
- stop超出索引范围:stop = -0
- 当start >= stop时,返回空列表
- lst[start: stop: step] step参数表示一次增加多少
- lst[8:3:-2] # step为负数的时候,反过来,此时start应该 >= stop
- lst[::-1] # 只有step, 全面反转
- lst[start:stop] 可以访问这个list一段, 从start开始, 到stop结束, 不包含stop,例如lst[3:7]
In [15]: lst = list(range(10))
In [16]: lst
Out[16]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [17]: lst[3] # 可以通过索引访问
Out[17]: 3
lst[start:stop] 可以访问这个list一段, 从start开始, 到stop结束, 不包含stop
In [18]: lst[3:7] # 从索引3开始, 到索引7结束, 不包含7, 返回新的list, 不会对原有的list做任何修改
Out[18]: [3, 4, 5, 6]
In [19]: lst[:4] # 当start为0时可以省略
Out[19]: [0, 1, 2, 3]
In [20]: lst[3:] # 当stop为-0的时候可以省略
Out[20]: [3, 4, 5, 6, 7, 8, 9]
In [21]: lst[:] # 都省略的时候等效于copy
Out[21]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [22]: lst[-5:-3] # 可以支持负数索引
Out[22]: [5, 6]
In [23]: lst[:100] # stop超出索引范围
Out[23]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [24]: lst[-100:] # stop超出索引范围
Out[24]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [25]: lst[-100:100] # 同时超出索引范围
Out[25]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
start超出索引范围:start = 0
stop超出索引范围:stop = -0
In [27]: lst[100:] # 和上两个结论冲突, lst[100:-1]
Out[27]: []
In [28]: lst[:-100] # 和上两个结论冲突, lst[0:-100]
Out[28]: []
In [29]: lst[100:-100] # 正向反向都超出的时候
Out[29]: []
In [30]: lst[3:1] # 当start > stop时,返回空列表
Out[30]: []
In [31]: lst[3:3] # 当start = stop时,也返回空列表
Out[31]: []
In [32]: lst[3:-1] # 负数索引, 实际上等于len(lst) + index, 10 + (-1) = 9
Out[32]: [3, 4, 5, 6, 7, 8]
负数索引实际上可以转换为len(lst) + index
当start为0时可以省略, 当stop为-0时可以省略
当stop <= start时, 返回空列表
当start超出索引范围start = 0, 当stop超出索引范围 stop 为-0
In [4]: def slice(lst, start=0, stop=0):
...: if start < 0:
...: start = len(lst) + start
...: if stop <= 0:
...: stop = len(lst) + stop
...: if stop <= start:
...: return []
...: if stop > len(lst):
...: stop = len(lst)
...: if start < 0:
...: start = 0
...: ret = []
...: for i, v in enumerate(lst):
...: if i >= start and i < stop:
...: ret.append(v)
...: return ret
...:
In [5]: slice(lst, -100, 100)
Out[5]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
lst[start: stop: step] step参数表示一次增加多少
In [3]: lst[3:8:2]
Out[3]: [3, 5, 7]
In [4]: lst
Out[4]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [5]: lst[8:3:-2] # step为负数的时候,反过来
Out[5]: [8, 6, 4]
In [2]: lst[::-1] # 只有step, 全面反转
Out[2]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
In [4]: def slice(lst, start=0, stop=0, step=1):
...: current = start
...: ret = []
...: while current < stop:
...: try:
...: ret.append(lst[current])
...: except IndexError:
...: pass
...: current += step
...: return ret
...:
In [5]: slice(lst, 0, 10, 1)
Out[5]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
当step为负数的时候
In [16]: def slice(lst, start=0, stop=0, step=1):
...: ret = []
...: current = start
...: if step > 0:
...: while current < stop:
...: try:
...: ret.append(lst[current])
...: except IndexError:
...: pass
...: current += step
...: if step < 0:
...: while current > stop:
...: try:
...: ret.append(lst[current])
...: except IndexError:
...: pass
...: current += step
...: return ret
...: