鍍金池/ 教程/ Python/ 列表(2)
標(biāo)準(zhǔn)庫 (4)
如何成為 Python 高手
標(biāo)準(zhǔn)庫 (6)
標(biāo)準(zhǔn)庫 (3)
類(2)
Pandas 使用 (2)
xml
用 tornado 做網(wǎng)站 (5)
文件(1)
練習(xí)
列表(3)
從小工到專家
除法
錯誤和異常 (2)
函數(shù)(1)
用 tornado 做網(wǎng)站 (7)
為做網(wǎng)站而準(zhǔn)備
函數(shù)練習(xí)
標(biāo)準(zhǔn)庫 (8)
Pandas 使用 (1)
回顧 list 和 str
字典(1)
用 tornado 做網(wǎng)站 (3)
字符串(1)
函數(shù)(2)
寫一個簡單的程序
將數(shù)據(jù)存入文件
語句(5)
SQLite 數(shù)據(jù)庫
集成開發(fā)環(huán)境(IDE)
集合(1)
類(1)
用 tornado 做網(wǎng)站 (6)
用 tornado 做網(wǎng)站 (2)
自省
語句(4)
錯誤和異常 (1)
用 tornado 做網(wǎng)站 (4)
集合(2)
列表(1)
標(biāo)準(zhǔn)庫 (1)
生成器
mysql 數(shù)據(jù)庫 (1)
第三方庫
實戰(zhàn)
運(yùn)算符
類(3)
字典(2)
語句(1)
數(shù)和四則運(yùn)算
語句(2)
文件(2)
MySQL 數(shù)據(jù)庫 (2)
電子表格
迭代器
mongodb 數(shù)據(jù)庫 (1)
特殊方法 (2)
特殊方法 (1)
字符編碼
編寫模塊
用 tornado 做網(wǎng)站 (1)
標(biāo)準(zhǔn)庫 (5)
函數(shù)(4)
類(5)
字符串(2)
關(guān)于 Python 的故事
函數(shù)(3)
字符串(4)
處理股票數(shù)據(jù)
常用數(shù)學(xué)函數(shù)和運(yùn)算優(yōu)先級
字符串(3)
為計算做準(zhǔn)備
多態(tài)和封裝
類(4)
迭代
語句(3)
錯誤和異常 (3)
分析 Hello
Python 安裝
標(biāo)準(zhǔn)庫 (2)
列表(2)
元組

列表(2)

上一節(jié)中已經(jīng)談到,list 是 Python 的苦力,那么它都有哪些函數(shù)呢?或者它或者對它能做什么呢?在交互模式下這么操作,就看到有關(guān)它的函數(shù)了。

>>> dir(list)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

上面的結(jié)果中,以雙下劃線開始和結(jié)尾的暫時不管,如__add__(以后會管的)。就剩下以下幾個了:

'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'

下面注意對這些函數(shù)進(jìn)行說明和演示。這都是在編程實踐中常常要用到的。

list 函數(shù)

append 和 extend

《列表(1)》中,對 list 的基本操作提到了 list.append(x),也就是將某個元素 x 追加到已知的一個 list 后邊。

除了將元素追加到 list 中,還能夠?qū)蓚€ list 合并,或者說將一個 list 追加到另外一個 list 中。按照前文的慣例,還是首先看官方文檔中的描述:

list.extend(L)

Extend the list by appending all the items in the given list; equivalent to a[len(a):] = L.

向所有正在學(xué)習(xí)本內(nèi)容的朋友提供一個成為優(yōu)秀程序員的必備:看官方文檔,是必須的。

官方文檔的這句話翻譯過來:

通過將所有元素追加到已知 list 來擴(kuò)充它,相當(dāng)于 a[len(a):]= L

英語太爛,翻譯太差。直接看例子,更明白

>>> la
[1, 2, 3]
>>> lb
['qiwsir', 'python']
>>> la.extend(lb)
>>> la
[1, 2, 3, 'qiwsir', 'python']
>>> lb
['qiwsir', 'python']

上面的例子,顯示了如何將兩個 list,一個是 la,另外一個 lb,將 lb 追加到 la 的后面,也就是把 lb 中的所有元素加入到 la 中,即讓 la 擴(kuò)容。

學(xué)程序一定要有好奇心,我在交互環(huán)境中,經(jīng)常實驗一下自己的想法,有時候是比較愚蠢的想法。

>>> la = [1,2,3]
>>> b = "abc"
>>> la.extend(b)
>>> la
[1, 2, 3, 'a', 'b', 'c']
>>> c = 5
>>> la.extend(c)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  TypeError: 'int' object is not iterable

從上面的實驗中,看官能夠有什么心得?原來,如果 extend(str)的時候,str 被以字符為單位拆開,然后追加到 la 里面。

如果 extend 的對象是數(shù)值型,則報錯。

所以,extend 的對象是一個 list,如果是 str,則 Python 會先把它按照字符為單位轉(zhuǎn)化為 list 再追加到已知 list。

不過,別忘記了前面官方文檔的后半句話,它的意思是:

>>> la
[1, 2, 3, 'a', 'b', 'c']
>>> lb
['qiwsir', 'python']
>>> la[len(la):]=lb
>>> la
[1, 2, 3, 'a', 'b', 'c', 'qiwsir', 'python']

list.extend(L) 等效于 list[len(list):] = L,L是待并入的 list

聯(lián)想到到上一講中的一個 list 函數(shù) list.append(),有類似之處。

extend(...) L.extend(iterable) -- extend list by appending elements from the iterable

上面是在交互模式中輸入 help(list.extend)后得到的說明。這是非常重要而且簡單的獲得文檔幫助的方法。

從上面內(nèi)容可知,extend 函數(shù)也是將另外的元素增加到一個已知列表中,其元素必須是 iterable,什么是 iterable?這個從現(xiàn)在開始,后面會經(jīng)常遇到,所以是要搞搞清楚的。

iterable,中文含義是“可迭代的”。在 Python 中,還有一個詞,就是 iterator,這個叫做“迭代器”。這兩者有著區(qū)別和聯(lián)系。不過,這里暫且不說那么多,說多了就容易糊涂,我也糊涂了。

為了解釋 iterable(可迭代的),又引入了一個詞“迭代”,什么是迭代呢?

盡管我們很多文檔是用英文寫的,但是,如果你能充分利用漢語來理解某些名詞,是非常有幫助的。因為在漢語中,不僅僅表音,而且能從詞語組合中體會到該術(shù)語的含義。比如“激光”,這是漢語。英語是從"light amplification by stimulated emission of radiation"化出來的"laser",它是一個造出來的詞。因為此前人們不知道那種條件下發(fā)出來的是什么。但是漢語不然,反正用一個“光”就可以概括了,只不過這個“光”不是傳統(tǒng)概念中的“光”,而是由于“受激”輻射得到的光,故名“激光”。是不是漢語很牛叉?

“迭”在漢語中的意思是“屢次,反復(fù)”。如:高潮迭起。那么跟“代”組合,就可以理解為“反復(fù)‘代’”,是不是有點“子子孫孫”的意思了?“結(jié)婚-生子-子成長-結(jié)婚-生子-子成長-...”,你是不是也在這個“迭代”的過程中呢?

給個稍微嚴(yán)格的定義,來自維基百科。“迭代是重復(fù)反饋過程的活動,其目的通常是為了接近并到達(dá)所需的目標(biāo)或結(jié)果?!?/p>

某些類型的對象是“可迭代”(iterable)的,這類數(shù)據(jù)類型有共同的特點。如何判斷一個對象是不是可迭代的?下面演示一種方法。事實上還有別的方式。

>>> astr = "Python"
>>> hasattr(astr,'__iter__')
False

這里用內(nèi)建函數(shù) hasattr()判斷一個字符串是否是可迭代的,返回了 False。用同樣的方式可以判斷:

>>> alst = [1,2]
>>> hasattr(alst,'__iter__')
True
>>> hasattr(3, '__iter__')
False

hasattr()的判斷本質(zhì)就是看那個類型中是否有__iter__函數(shù)??垂倏梢杂?dir()找一找,在數(shù)字、字符串、列表中,誰有__iter__。同樣還可找一找 dict,tuple 兩種類型對象是否含有這個方法。

以上穿插了一個新的概念“iterable”(可迭代的),現(xiàn)在回到 extend 上。這個函數(shù)需要的參數(shù)就是 iterable 類型的對象。

>>> new = [1,2,3]
>>> lst = ['Python','qiwsir']
>>> lst.extend(new)
>>> lst
['Python', 'qiwsir', 1, 2, 3]
>>> new
[1, 2, 3]

通過 extend 函數(shù),將[1,2,3]中的每個元素都拿出來,然后塞到 lst 里面,從而得到了一個跟原來的對象元素不一樣的列表,后面的比原來的多了三個元素。上面說的有點啰嗦,只不過是為了把過程完整表達(dá)出來。

還要關(guān)注一下,從上面的演示中可以看出,lst 經(jīng)過 extend 函數(shù)操作之后,變成了一個貌似“新”的列表。這句話好像有點別扭,“貌似新”的,之所以這么說,是因為對“新的”可能有不同的理解。不妨深挖一下。

>>> new = [1,2,3]
>>> id(new)
3072383244L

>>> lst = ['python', 'qiwsir']
>>> id(lst)
3069501420L

id()能夠看到兩個列表分別在內(nèi)存中的“窩”的編號。

>>> lst.extend(new)
>>> lst
['python', 'qiwsir', 1, 2, 3]
>>> id(lst)
3069501420L

看官注意到?jīng)]有,雖然 lst 經(jīng)過 extend()方法之后,比原來擴(kuò)容了,但是,并沒有離開原來的“窩”,也就是在內(nèi)存中,還是“舊”的,只不過里面的內(nèi)容增多了。相當(dāng)于兩口之家,經(jīng)過一番云雨之后,又增加了一個小寶寶,那么這個家是“新”的還是“舊”的呢?角度不同或許說法不一了。

這就是列表的一個重要特征:列表是可以修改的。這種修改,不是復(fù)制一個新的,而是在原地進(jìn)行修改。

其實,append()對列表的操作也是如此,不妨用同樣的方式看看。

說明:雖然這里的 lst 內(nèi)容和上面的一樣,但是,我從新在 shell 中輸入,所以 id 會變化。也就是內(nèi)存分配的“窩”的編號變了。

>>> lst = ['Python','qiwsir']
>>> id(lst)     
3069501388L
>>> lst.append(new)
>>> lst
['Python', 'qiwsir', [1, 2, 3]]
>>> id(lst)
3069501388L

顯然,append()也是原地修改列表。

如果,對于 extend(),提供的不是 iterable 類型對象,會如何呢?

>>> lst.extend("itdiffer")
>>> lst
['python', 'qiwsir', 'i', 't', 'd', 'i', 'f', 'f', 'e', 'r']

它把一個字符串"itdiffer"轉(zhuǎn)化為['i', 't', 'd', 'i', 'f', 'f', 'e', 'r'],然后將這個列表作為參數(shù),提供給 extend,并將列表中的元素塞入原來的列表中。

>>> num_lst = [1,2,3]
>>> num_lst.extend(8)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable

這就報錯了。錯誤提示中告訴我們,那個數(shù)字 8,是 int 類型的對象,不是 iterable 的。

這里講述的兩個讓列表擴(kuò)容的函數(shù) append()extend()。從上面的演示中,可以看到他們有相同的地方:

  • 都是原地修改列表
  • 既然是原地修改,就不返回值

原地修改沒有返回值,就不能賦值給某個變量。

>>> one = ["good","good","study"]
>>> another = one.extend(["day","day","up"])    #對于沒有提供返回值的函數(shù),如果要這樣,結(jié)果是:
>>> another                                     #這樣的,什么也沒有得到。
>>> one
['good', 'good', 'study', 'day', 'day', 'up']

那么兩者有什么不一樣呢?看下面例子:

>>> lst = [1,2,3]
>>> lst.append(["qiwsir","github"])
>>> lst
[1, 2, 3, ['qiwsir', 'github']]  #append 的結(jié)果
>>> len(lst)
4

>>> lst2 = [1,2,3]
>>> lst2.extend(["qiwsir","github"])
>>> lst2
[1, 2, 3, 'qiwsir', 'github']   #extend 的結(jié)果
>>> len(lst2)
5

append 是整建制地追加,extend 是個體化擴(kuò)編。

count

上面的 len(L),可得到 list 的長度,也就是 list 中有多少個元素。python 的 list 還有一個函數(shù),就是數(shù)一數(shù)某個元素在該 list 中出現(xiàn)多少次,也就是某個元素有多少個。官方文檔是這么說的:

list.count(x)

Return the number of times x appears in the list.

一定要不斷實驗,才能理解文檔中精煉的表達(dá)。

>>> la = [1,2,1,1,3]
>>> la.count(1)
3
>>> la.append('a')
>>> la.append('a')
>>> la
[1, 2, 1, 1, 3, 'a', 'a']
>>> la.count('a')
2
>>> la.count(2)
1
>>> la.count(5)     #NOTE:la 中沒有 5,但是如果用這種方法找,不報錯,返回的是數(shù)字 0
0

index

《列表(1)》中已經(jīng)提到,這里不贅述,但是為了完整,也占個位置吧。

>>> la
[1, 2, 3, 'a', 'b', 'c', 'qiwsir', 'python']
>>> la.index(3)
2
>>> la.index('qi')      #如果不存在,就報錯
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  ValueError: 'qi' is not in list
>>> la.index('qiwsir')
6

list.index(x),x 是 list 中的一個元素,這樣就能夠檢索到該元素在 list 中的位置了。這才是真正的索引,注意那個英文單詞 index。

依然是上一條官方解釋:

list.index(x)

Return the index in the list of the first item whose value is x. It is an error if there is no such item.

是不是說的非常清楚明白了?


總目錄   |   上節(jié):列表(1)   |   下節(jié):列表(3)

如果你認(rèn)為有必要打賞我,請通過支付寶:qiwsir@126.com,不勝感激。

上一篇:集合(1)下一篇:類(4)