一個有趣的問題
list = []
list[0] = 1
為什么會這樣?
因為我們定義的列表的長度就是0,使用索引當然失敗
可以使用 .append(),就不會報錯
如果我想使用索引來增加末尾的元素呢?
list = [0,1,2]
list.append(None)
list[3] = 3
如果想使用索引,前提是該位置必須存在
數組
什么是數組?
array,有限個相同類型 的變量組成的有序集合
-
有限,數組是有限的
-
相同類型,數組中的元素是同種類型的
-
有序,數組在內存中是順序存儲的
在Python中列表和元組就是對數組的封裝
數組的基本操作(在Python中就是list唄)
讀取操作
對於列表使用索引法就OK了
更新元素
直接使用索引,賦值即可
插入元素
-
尾部插入
使用方法 .append()
-
中間插入
使用方法 .insert()
-
超范圍插入
當數組已經滿了,但是還是想要插入元素,這個時候就是所謂的超范圍插入
使用列表方法並沒有問題
尾部插入和中間插入的區別:
尾部插入直接在列表最后增加位置,並賦值即可;如果列表長度足夠,那么一開始就不用增加位置,直接賦值即可
中間插入:插入的位置(包括該位置)后的所有元素后移一位,然后直接賦值即可;如果長度不夠,也就是超范圍了,那么要么加一位,要么簡單點直接倍增元素
尾部插入的代碼實現
class MyArray:
def __init__(self,capacity):
self.array = [None]*capacity# 初始化列表,長度為4
self.size = 0# 列表有效元素的長度,剛開始就是零
def insert(self,index,sth):
if index < 0 or index > self.size:# 插入位置越界,拋出
raise Exception# 這里注意一個點,插入也是只能插入有效的位置才行,比如長度=0只能在0處插入
else:
for i in range(self.size-1,index-1,-1):# 從最后一位到插入位置(包括該位置),后移一位
self.array[i+1] = self.array[i]
self.array[index] = sth# 對該位置直接賦值
self.size += 1# 列表有效元素實際長度加1
def output(self):# 輸出列表
print(len(self.array))
for i in range(0,self.size,1):
print(self.array[i],end=" ")
array = MyArray(4)# 實例化
array.insert(0,10)# 插入
array.insert(0,9)
array.insert(1,7)
array.insert(2,8)
# 這里只能先在0處插入,然后可以在0.1處插入,然后可以在0.1.2處插入。最多插入四個,因為插入四個之后,數組就# 滿了。那么如何超范圍插入呢?
array.output()
中間插入代碼實現
class MyArray():
def __init__(self,capacity):
self.array = [None]*capacity
self.size = 0
def insert_v2(self,index,element):
if index < 0 or index > self.size:# 如果越界,拋出
raise Exception
elif self.size >= len(self.array):# 如果實際長度大於列表長度,重新為列表分配空間
self.resize()# 1. 使用函數倍增數組空間
# self.array.append(None)# 2. 使用方法僅增加需要的一位空間
for i in range(self.size-1,-1,-1):# 從最后一位到插入位置(包括該位置),后移一位
self.array[i+1] = self.array[i]
self.size += 1# 實際長度加1
self.array[index] = element# 插入位置直接賦值
def resize(self):
array_new = [None]*len(self.array)*2# 簡單粗暴方式,那就是如果我列表長度不夠,直接擴大兩倍
for i in range(self.size):
array_new[i] = self.array[i]# 依次復制
self.array = array_new# 列表是對象傳遞,self.array指向新的列表對象
def out_put(self):
for i in range(len(self.array)):
print(self.array[i],end=" ")
array = MyArray(4)
array.insert_v2(0,0)
array.insert_v2(0,1)
array.insert_v2(0,2)
array.insert_v2(0,3)
array.insert_v2(0,4)
array.insert_v2(1,0)
# 誠然,直接加倍是簡單粗暴的方式,還有一種重新分配空間的方式,那就是直接使用.append這個方法,超出之后就每# # 加個數就擴容一次,見上面注釋掉的部分
array.out_put()
擴展:如果是刪除元素呢?
相關的有三個方法:
-
.pop([index])
如果沒有index,那么默認彈出最后一位,返回值就是彈出值
-
del list[index] (這個不是方法)
del 這個可以刪除列表本身,也可以刪除某一位,沒有返回值,且徹底刪除
-
.remove(obj)
刪除遇到的第一個obj,如果列表有復數的obj,那么意味着要用for循環刪干凈
擴展一下,list.count(obj),返回obj在列表中出現的次數
for i in range(list.count(obj)):list.remove(obj)
刪除元素
辨析:
數組的插入是從后往前挪騰元素,然后空出位置給新元素;
類似的,刪除元素也需要挪騰元素,只不過這次是來補位,把刪掉元素空出來的位置補掉
Python中方法
.pop([index])
del
.remove(obj)
對上述代碼補充如下:
class MyArray():
def __init__(self,capacity):
self.array = [None]*capacity
self.size = 0
def insert_v2(self,index,element):
if index < 0 or index > self.size:# 如果越界,拋出
raise Exception
elif self.size >= len(self.array):# 如果實際長度大於列表長度,重新為列表分配空間
# self.resize()
self.array.append(None)
for i in range(self.size-1,index-1,-1):# 從最后一位到插入位置(包括該位置),后移一位
self.array[i+1] = self.array[i]
self.size += 1# 實際長度加1
self.array[index] = element# 插入位置直接賦值
def resize(self):
array_new = [None]*len(self.array)*2
for i in range(self.size):
array_new[i] = self.array[i]
self.array = array_new
def romove(self,index):
if index < 0 and index > self.size:
raise Exception
else:
while index < self.size-1:# 從index到self.size-1-1
self.array[index] = self.array[index+1]
index += 1
self.size -= 1 # 實際長度-1
self.array.pop()# 彈出最后空缺的位置
def output(self):
for i in range(self.size):
print(self.array[i],end=" ")
c3 = MyArray(4)
c3.insert_v2(0,0)
c3.insert_v2(1,1)
c3.insert_v2(2,2)
c3.insert_v2(3,3)
c3.insert_v2(4,4)
c3.insert_v2(5,5)
print("數組如下:")
c3.output()
print("\n刪除之后的是:")
c3.romove(1)
c3.output()