天天看點

給妹子講python-S01E01好用的清單

【妹子說】今天開始學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]           

原文釋出時間為:2018-07-17

本文作者:醬油哥

本文來自雲栖社群合作夥伴“

Python愛好者社群

”,了解相關資訊可以關注“