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, 全面反轉
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
    ...: 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章