線性結構與切片
線性結構
- 列表、元組、字符串、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
...: