1.python中的容器數據類型概述
2.列表類型的異構性、有序性和本地可變性三大優勢
2.列表的基本操作(增、刪、改、分片索引)
3.列表的分片賦值與本地排序
【妹子說】今天開始學python啦,不過我們從哪裡開始學起呢?
Python中有一種被稱之為“容器”的數據類型,專門用來存放其他類型的對象,就好比小時候用的文具盒,裡面放著鉛筆、尺子、橡皮等等。很多人剛剛使用Python的時候,往往最先接觸的就是這種容器對象,比如列表、字典、元組等等。它們功能全面,使用也很方便,可以解決很多實際問題。
那麼,第一季我們就首先從這些好用、實用的python容器入手吧,第一個就介紹列表:
Python列表用起來非常靈活,它有三大優點,我們一個一個來說,聊完了這三個優點,基本上列表的基本操作我們就掌握了:
列表裡想裝啥就裝啥,即:他可以包含不同種類、任意類型的對象,甚至可以嵌套列表,專業點的詞兒叫:異構性;
我們看一個例子:
L1 = [1, 2, 3, 4, 5]
L2 = [1, 'spam', [2.3, 4]]
L3 = []
看這三個列表的初始化過程,異構性就搞清楚了,特別是L2列表,它同時包含了好幾種不同的數據類型,甚至還嵌套了列表。
列表裡裝的元素都是有順序的,可以按照位置序號獲取單個元素,也可以用分片的方法來進行多個連續元素的獲取,來個專業詞匯,叫做:有序性。
按位置序號索引,例如L1[2]這種方式來訪問列表中的元素只是最簡單的一種,我來重點來說說分片操作這個獨特用法,先看看這個例子:
L = [1,2,3,4,5,6,7,8]
print(L[1:3])
[2, 3]
我們從列表L中從左往右截取了一個片段。關於截取片段左右邊界與索引值的對應關系,我們只需記住這麼一個口訣“左閉右開”就OK了:
分片索引中第一個參數1表示左側開始的索引1(從0開始計數),因此起始的元素就是整形數2,第二個參數3表示在右側終止的索引值為3,即整形數4,但要記住他是不包含在截取的序列中的。
分片還有幾種常見用法:
如果省略掉終止索引,就表示一直截取到末尾:
L = [1,2,3,4,5,6,7,8]
print(L[1:])
[2, 3, 4, 5, 6, 7, 8]
同理,如果省略掉起始索引,就表示從起始元素就開始截取:
L = [1,2,3,4,5,6,7,8]
print(L[:4])
[1, 2, 3, 4]
還可以用負索引,目前我們使用的都是正索引,即從左往右的索引值,最左側的索引值為0,往右依次加1;還有一種負索引的表示法,即從右往左數,最右側是-1,往左依次減1,即-2,-3以此類推:
L = [1,2,3,4,5,6,7,8]
print(L[3:-1])
[4, 5, 6, 7]
【妹子問】:那我想跳著截取呢?
那就用上第三個參數,步進值參數,這個默認是1,即1個挨著1個的取,如果我們想跳著截取,那就得專門設置這個步進參數了。
L = [1,2,3,4,5,6,7,8]
print(L[0::2])
[1, 3, 5, 7]
這時候【妹子問了一個很有內涵的問題】:我對截取出的分片進行修改,會影響到原始的列表嗎?
那我們還是眼見為實:
L = [1,2,3,4,5,6,7,8]
b = L[3:-1]
print('before change:b={}'.format(b))
b[0]=111
print('after change:b={}'.format(b))
print('after change:L={}'.format(L))
before change:b=[4, 5, 6, 7]
after change:b=[111, 5, 6, 7]
after change:L=[1, 2, 3, 4, 5, 6, 7, 8]
很明顯,對原始列表L進行分片切割後,產生了一個全新的列表。用變量b獲取了L的分片後,實質是獲取了L分片的一個新的獨立拷貝。因此,你在列表b上做修改,是影響不了L的。
列表的大小和內容可以隨意改變,在插入、刪除、修改列表元素時,不需要建立一份新的列表拷貝,而是在原來的內存地址上直接修改列表對象。這個叫“本地可修改”
首先看增加新元素的三個使用場景:
L = [1,2,3,4]
L.append(5)
print(L)
[1, 2, 3, 4, 5]
L = [1,2,3,4]
L.insert(1,10)
print(L)
[1, 10, 2, 3, 4]
L = [1,2,3,4]
L.extend([11,22,33])
print(L)
[1, 2, 3, 4, 11, 22, 33]
這三個用法有些不同,append方法只能在尾部加入;insert方法可在任意位置加入,比如上面例子,我們在列表的索引位置為1的地方加入元素10,如果指定的索引值大於序列的總長度,則自動加到末尾;extend方法則可以在尾部一次性加入多個元素
這時,【妹子自己操作了一把】:
L = [1,2,3,4,5]
L = L.insert(6,2)
print(L[2])
Traceback (most recent call last):
File "E:/12homework/12homework.py", line 3, in <module>
print(L[2])
TypeError: 'NoneType' object is not subscriptable
然後,就沒有然後了。。。這裡犯了一個常見的錯誤,因為我們說過插入是就地修改,而不是返回修改後的新列表。Insert方法的返回值是None,這麼干換句話說,會徹底失去之前列表的引用,因為你把None值賦給了L,你就無法找到之前的列表了。append和extend方法也是這樣。
刪除,依據使用需求也有這幾種使用場景:
最簡單直接的,用remove方法,傳入指定要刪除的對象,注意:它也是在原列表上就地刪除,返回值為None
L1 = ['aa','bb','cc']
L1.remove('aa')
print(L1)
['bb', 'cc']
這裡注意,還有一個內置方法del,它額外的功能是可以刪除列表中的一個分片
del L1[1:3]
還有一個pop方法,它在末端刪除一個元素,並可以將刪除的元素作為返回值返回給調用者
L1 = [1,2,3]
print(L1.pop())#末端刪除一個元素,彈出刪除的值
print(L1)
3
[1, 2]
【妹子問】那麼元素修改,除了像下面這種直接用索引做元素修改的情況外,還有什麼有趣的用法?
L = [4,5,6,7,8,9]
L[0] = 0
那必須要來點有意思的,主要就說分片賦值和本地排序這兩個問題:
L = [4,5,6,7,8,9]
L[1:3] = ['aa','bb','cc','dd']
print(L)
[4, 'aa', 'bb', 'cc', 'dd', 7, 8, 9]
分片賦值的本質是先在原列表上刪除指定分片,然後在刪除的位置插入新的列表,因此左右兩邊的長度可以不等。
本地排序非常方便,看看下面的例子就明白了。注意排序也是在本地修改,而不是將排好序的列表作為返回值返回。
L = [1,5,3,8,3,2,10]
L.sort()
print(L)
L.reverse()
print(L)
[1, 2, 3, 3, 5, 8, 10]
[10, 8, 5, 3, 3, 2, 1]
【妹子說】果然呀,所謂三大優點講完了,列表的基本用法算是弄明白了,那下次再講講字典和元組吧。