0基礎學Python之十二:列表(中)

https://www.zhihu.com/video/969171525455212544

Hi 大家好,我是王可樂。歡迎回到可樂的從零開始學Python課程。今天我們繼續來講Python中的一個重要數據類型:列表。從上節課的內容里,我們了解到,列表是一個有序的集合類型數據。既然是一個有序的集合類型數據,那我們就能用循環語句來一一訪問,也就是遍歷,列表中的各個元素。我們來看一下:

>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9] # 首先,我們定義一個列表 a>>> for i in a:... print(i*2) # 在循環體內,我們用 print 列印每個元素乘以 2 的值...24681012141618

這種 for in 形式的循環我們在前面已經見到過,可以看到 Python 依次為我們列印了每一個元素乘以 2 之後的值。

我們還可以用另一種方式來進行列表元素的遍歷,就是使用索引來進行遍歷。例如:

>>> for i in range(len(a)):... print(a[i]*2) # 循環體內,我們列印第 i 個元素乘以 2 的值...24681012141618

可以看到,和上面程序的輸出結果是一樣的。區別是上面的代碼是直接遍歷列表元素,而下面的代碼是通過索引來遍歷。這裡有一點需要注意,我們之前看到的使用 range 對象產生連續數字都是傳入兩個參數,一個開頭一個結尾,最終的序列包含開頭而不包含結尾。這裡我們使用 range 對象時只傳入了一個參數,它的意思是開頭元素默認為 0,而我們傳入的參數則等同於之前用法的第二個參數。

這兩種方式適合於不同場景的使用。舉個例子,如果,你想使用列表來保存一個矩陣,你一定會更喜歡使用索引來引用數組中的元素。

>>> a=[[1,2,3],[1,2,3],[1,2,3]] # 我們定義數組 a,其中的元素都是長度為 3 的數組>>> for i in range(len(a)): # 然後我們一一訪問數組裡的每個元素... for j in range(len(a[i])):... print(i, j, a[i][j])...0 0 10 1 20 2 31 0 11 1 21 2 32 0 12 1 22 2 3

在這裡,a 是一個長度為 3 的數組,而數組中的每一個元素都是長度為也 3 的數組。這個數據結構我們可以理解為是一個二維的數組,可以認為 a 的每一個元素是一行,而每一行都有三個元素,也就是二維數組有三個列。使用 a[i][j] 可以訪問第 i 行第 j 列的元素,可以看到,我們這裡輸入的雙重循環使用下標,依次列印了這個二維數組中的所有元素。

熟悉我們前面課程的同學,一定還記得如何使用關鍵字 in 來判斷一個字元是否存在於字元串中吧?那麼如何某個元素是否存在於列表中呢?沒錯,還是使用關鍵字in。例如:

>>> [1,2,3] in aTrue

當然我們也可以使用上節課中提到過的index函數來判斷,如果index函數不報錯,返回一個整數索引值,那說明元素存在於列表中。否則,index函數會報錯。例如:

>>> a.index([1,2,3])0>>> a.index("Tom")Traceback (most recent call last): File "<stdin>", line 1, in <module>ValueError: Tom is not in list

index 函數報錯說 Tom 不存在於列表 a 中。

類似於字元串操作,如果你想統計某個元素在列表中的個數,也可以使用 count函數。

>>> a.count([1,2,3])3

那麼,如果我想從一個列表中取出一些元素,構成一個新的列表,這該如何做呢?例如,輸入:

>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9] # 定義列表 a 保存 9 個整數

如果我們想要取出 a 的前三個元素,可以這樣:

>>> b = [a[0], a[1], a[2]]>>> b # 可以看到,我們達到了目的[1, 2, 3]

不過,你還記得前面學習字元串的課程中,我們演示過的字元串截取、分片方法嗎?沒錯,列表也是支持類似的分片操作的。例如,上面的例子我們只需要輸入:

>>> c = a[0:3]>>> c # 然後再來看一下,結果一模一樣[1, 2, 3]

我們再來溫習一下。這裡,列表a後面的方括弧里,我們寫入了兩個索引號。第一個是分片起始元素在原列表的索引,第二個是分片最後一個元素索引加一。和字元串操作類似,上一節課中我們提到過的負數索引也可以使用在分片里。下面是一個例子。

>>> a[1:-1][2, 3, 4, 5, 6, 7, 8] # 可以看到,我們截取了除去開頭和結尾的兩個元素>>> a[1:] # 和字元串操作類似,省略後一個索引意味著一直取到最後一個元素[2, 3, 4, 5, 6, 7, 8, 9] # 可以看到,新產生的列表包含了第二個及以後的所有元素

如果我們省略冒號前面第一個數字呢?大家回憶一下字元串課程中類似的內容,自己嘗試一下吧。

講到這裡可能又有一些愛動腦筋的朋友們會問,既然列表是個數據類型,是不是支持四則運算呢?這是個很有意思的問題,能問出這樣的問題,說明朋友們已經開始具備編程的思維了。事實上,列表確實支持+和*操作符,但不支持-和/。

和字元串類似,對於列表來說,+號操作符就是就是把兩個列表連接成一個列表。例如:

>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9] # 我們重新定義一個列表 a>>> b = [1, 2, 3] # 以及一個列表 b>>> a + b # 輸入 a + b[1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3]

可以看到,產生了一個大的數組。這個結果是不是有些面熟呢?沒錯,a=a+b這個列表操作等價於a.extend(b)。

列表的 *號操作符也和字元串的 * 號操作符類似,就是把鏈表內的元素重複多份,產生一個新的列表。例如:

>>> b # 我們看一下列表 b,還是 123[1, 2, 3]>>> b * 3 # 輸入 b * 3[1, 2, 3, 1, 2, 3, 1, 2, 3]

可以看到,產生了一個把 列表 b 重複了三次的新列表。

好了,到這裡,可樂已經為大家介紹了列表的很多知識了。又掌握了一門利器,咱們趕緊來一起試一試吧。我們來寫個計算質數的小程序,這個程序的代碼大家可以在我們「可樂編程」公眾號本節課的文本中找到,也可以掃描屏幕上的二維碼,訪問可樂的代碼倉庫來下載。

gitee.com/colecode/pyth (二維碼自動識別)

import mathcal_range = int(input("請輸入計算質數的範圍:"))prime_nums = []for i in range(cal_range+1): if i == 0 or i == 1: continue num = 2 while num <= math.sqrt(i): if i % num == 0: break else: num += 1 if num > math.sqrt(i): prime_nums.append(i)for i in prime_nums: print(i)

質數是什麼大家應該都了解吧?可樂就不多廢話了。咱們來看看程序,這個程序包含了我們前幾期講到的一些知識點,也有一些新的內容。

首先,程序第一行 import math 引入了Python 內置的數學模塊。模塊和 import 語句背後的邏輯各位朋友現在不用關心,可樂會在後面的課程中涉及。現在,你只要知道引入了這個模塊之後,我們就能在下面的程序里使用sqrt這個函數就可以了,而 sqrt 這個函數則可以幫助我們計算一個數的平方根。

由於質數有無窮多個,我們這裡只計算有限個,因此我們需要一個上限,我們的程序將求出從0到這個上限數字之間所有的質數。這裡,我們讓用戶來輸入一個數字作為上限,使用了內置函數 input 函數。我們在第二課猜數字遊戲的例子中看到過這個函數,它接受一個字元串作為參數,然後在屏幕上列印這個字元串作為提示,並等待用戶輸入。用戶輸入任意字元後回車,input 會把用戶的輸入字元串返回給調用者。這裡,我們需要用戶輸入的是一個數字,因此我們用 int() 函數把 input 返回的輸入從字元串轉換成一個整數。

接下來,我們定義了一個空的列表,用於存放計算得到的素數。然後,我們開始一個循環,從數字 0 開始到上限為止,挨個判斷這個數字是不是質數。這裡我們給 range 傳入的參數是 cal_range+1,這是為了包含進用戶輸入的這個數字。

在循環體內,我們判斷當前的 i 是否是質數。我們都知道0,1不是質數,因此可以直接跳過它們。然後,我們回憶一下質數的定義:一個質數只有1和它本身兩個數可以將它整除。因此,對於 2 及以後的所有數字 i,我們用了一個while循環來嘗試它每一個可能的除數。

我們只需要判讀小於這個數平方根的數字即可,因此我們在 while 循環中從 2 嘗試到 i 的平方根為止。在 while 循環里,一旦有一個數可以整除 i,那麼意味著 i 不是質數,於是我們 break 跳出循環;而如果從 2 到 sqrt(i) 為止循環都沒有被 break 跳出,此時的 num 一定是大於 sqrt(i) 的了。

我們就根據 while循環結束後 num 的值來判斷循環內是否遇到了能夠整除 i 的數字。如果 num 大於 sqrt(i),說明循環沒有被 break,那麼就意味著沒有找到能夠整除 i 的數字,i 就是質數了。這時,我們把這個質數放到之前定義的結果列表prime_nums 里。最後,for 循環執行完備之後,我們把這個列表列印出來。

好啦,請你嘗試一下,把這個程序保存為prime.py,然後運行一下這個小程序試試看,在終端中輸入:python prime.py

接著,只要輸入一個整數範圍,很快就能得到範圍內的所有質數。這裡,可樂要提醒大家,不要輸入過大的值,不然很可能導致程序很久都停不下來哦。事實上,這個求質數的演算法並不是最高效的方法。以後有機會給大家講演算法的時候,可樂再和大家聊一聊有趣的演算法知識。

好了,今天的課程里,可樂為大家介紹了如何在循環中遍歷列表,以及列表支持的運算符。最後,我們結合之前講授過的內容,寫了一個求質數的小程序。本次課的內容不少哦,特別是最後求質數的小程序,不知道大家是否完全看明白了。可樂強烈建議大家自己把這個程序輸入一遍,自己嘗試一下,加深理解哦。

如果你遇到了什麼問題,歡迎在我們的「可樂編程」公眾號後台提問,可樂會儘快回復的。

下節課我們還將繼續列表的話題,還會有更多有意思的Python程序等著大家,記得一定要看哦,那麼下回再見咯。


推薦閱讀:

快速教程:使用Cython來擴展Python/NumPy庫
abaqus的二次開發為何用python語言?
新手向:十個趣味性Python腳本
pyecharts + Flask&amp;Django,該來的總是要來的
Flask連接資料庫打怪升級之旅

TAG:Python | 零基礎 | 編程 |