[python] [VI coding] 第十章 列表 - 教學區

[python] [VI coding] 第十章 列表

文章瀏覽次數 95

特種兵

特種兵圖像(預設)

2021-07-16 15:39:57

From:211.23.21.202

第十章 列表

本章介紹 python 中,最常用的基本複合型態:列表。透過本章可以了解物件,並學到當有許多類似的變數需求時,應該如何使用列表來集合它們。

10-1 列表是個有序序列

列表有點像是字串,它是有序的序列。在字串中,每個最小單元是字元,但在列表中,單元可以是各種型態的元素。

列表中的成員通常稱為元素或者項目。有幾種方法可以建立列表,最簡單的方式是將元素放進中括號 [ ] 裡:

[10, 20, 30, 40]
# 上面列表中有 4 個整數元素
['crunchy frog', 'ram bladder', 'lark vomit']
# 上面列表中有 3 個字串元素

列表中的元素可以是不同的資料型態,以下例子的列表包含整數、浮點數、字串以及另一個整數列表:

[5, 2.0, 'spam', [10, 20]]

這種列表中含有列表的情況,稱為「巢狀」列表。

一個不含任何元素的列表稱為空列表,也就是只有一對 [ ],可以把值加進去,成為新的列表元素。

下面的例子是使用 print 來印出三個列表,其中 empty 是一個空列表:

>>> cheeses = ['Cheddar', 'Edam', 'Gouda']
>>> numbers = [17, 123]
>>> empty = []
>>> print(cheeses, numbers, empty)
['Cheddar', 'Edam', 'Gouda'] [17, 123] []

注意:print 內的逗號是 print 語法的一部分,並不會被印出來,它的作用是預設以空一格來分隔不同元素。

10-2 列表是可變的

想要取得列表元素的語法跟字串取得字元一樣,使用 [ ] 就可以了。中括號裡面的數字稱為索引或下標,記得順序一樣是從 0 開始計算。

>>> cheeses = ['Cheddar', 'Edam', 'Gouda']
>>> print(cheeses[0])
Cheddar

上面的範例,使用 print 只印出整個列表中的第一個元素。

列表與字串不同的地方在於列表是可變的,可以直接使用索引的方式改變列表裡元素的值:

>>> numbers = [17, 123]
>>> numbers[1] = 5
>>> print(numbers)
[17, 5]

在上例中,第2個元素,也就是索引1的 123,被改成 5 了。

由上面的例子,來思考一下元素個數與索引的關係或特點:

  1. 任何整數都可以當作索引,注意是「整」數。
  2. 如果你嘗試讀寫不存在的元素,則會發生 IndexError 的索引錯誤。
  3. 如果索引是負的,則會從列表最尾端的元素開始往前數,例如 -1 是最後一個元素。

之前提過的 in 這個運算子也可以用於列表,判斷某元素是否存在於該列表中:

>>> cheeses = ['Cheddar', 'Edam', 'Gouda']
>>> 'Edam' in cheeses
True
>>> 'Brie' in cheeses
False

在上例中,沒有使用 if 關鍵字,因為有比較運算子的判斷式就是一個完整的式子,它會回應 True 或 False,而在 python 主控臺也不需要使用 print 就能直接得到結果。

10-3 遍歷列表

想遍歷列表的方法有很多,其中一種是使用 for 迴圈,跟之前的遍歷字串是一樣的:

cheeses = ['Cheddar', 'Edam', 'Gouda']
for cheese in cheeses:
	print(cheese)
# 執行結果:
# Cheddar
# Edam
# Gouda

若只是讀取列表,這個方式很有效。如果想寫入列表,也就是想更動列表裡的元素值,那就需要 range() 函數搭配 len() 函數來使用:

numbers = [10, 20, 30]
for i in range(len(numbers)):
	numbers[i] = numbers[i] * 2
# 執行結果:
# 20
# 40
# 60

這個迴圈更新列表裡的每個元素,每個元素都乘以 2。

len: 可以回傳列表裡的元素個數,這裡是 3。

range 產生 0 到 n-1 的列表,這裡是 0 到 3-1,也就是 0, 1, 2 的索引。

下面的範例是運算式的縮寫:

a = a + b 可以寫成 a += b
a = a - b 可以寫成 a -= b
a = a * b 可以寫成 a *= b
a = a / b 可以寫成 a /= b
a = a % b 可以寫成 a %= b

注意:若 for 迴圈遇到一個空列表,則不會執行迴圈主體,迴圈會被跳過,如下範例:

for x in []:
	print('這行不會被列印出來')

之前提過巢狀列表,內層的列表實際上只算一個元素,以下的列表是 4 個元素:

data = ['小明', 176, ['水果', '餅乾', '飲料'], [100, 95, 85]]

根據上例,以下範例顯示其中一個巢狀列表之值:

print(data[2])
# ['水果', '餅乾', '飲料']
for food in data[2]:
	print(data[0], '愛', food)
# 顯示結果:
# 小明 愛 水果
# 小明 愛 餅乾
# 小明 愛 飲料

根據上例,以下範例會將巢狀列表也遍歷一遍,逐行顯示每個元素之值:

for i in data:
	if isinstance(i, list):
		for j in i:
			print(j)
	else:
		print(i)

isinstance() 函數用來判斷變數的資料型態。如果是列表,則再跑一次迴圈,將列表的每個元素逐一印出;如果是單純元素,就直接印出。

10-4 列表運算子操作

加號運算子 + 可以用來連接列表,就像連接字串:

>>> a = [1, 2, 3]
>>> b = [4, 5]
>>> c = a + b
>>> c
[1, 2, 3, 4, 5]

乘號運算子 * 在給予數字的情況下會重複拼接列表,就像字串重複連接:

>>> [0] * 4
[0, 0, 0, 0]
>>> [1, 2, 3] * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]

10-5 列表切片

字串切片的運算也可以作用在列表上:

>>> t = ['a', 'b', 'c', 'd', 'e', 'f']
>>> t[1:3]
['b', 'c']
>>> t[:4]
['a', 'b', 'c', 'd']
>>> t[3:]
['d', 'e', 'f']
>>> t[:]
['a', 'b', 'c', 'd', 'e', 'f']

如果省略第一個索引,表示從開頭起算;如果省略第二個索引,表示直到結尾;兩者都省略,就表示複製整個列表。

另外,由於列表是可變的,修改前先複製一份,是個保險做法。

切片索引可以用來一次變更多個元素:

>>> t = ['a', 'b', 'c', 'd', 'e', 'f']
>>> t[1:3] = ['x', 'y']
>>> t
['a', 'x', 'y', 'd', 'e', 'f']

當比較運算子兩邊指定的範圍個數不同時,注意一下產生的結果:

>>> t = ['a', 'b', 'c', 'd', 'e', 'f']
>>> t[:3] = ['x']
['x', 'd', 'e', 'f']
# 上面的例子是把索引 0:3 的範圍元素取代成 x,所以元素變少了。
>>> t[:3] = ['aa', 'bb', 'cc', 'dd']
['aa', 'bb', 'cc', 'dd', 'f']
# 上面的例子是把索引 0:3 的範圍元素取代成 aa, bb, cc, dd,所以元素變多了。

結論:列表切片使用等號是接近取代的用途,並非直接賦值,因此當範圍元素與取代元素個數不同時,不會發生錯誤。

10-6 列表方法

python 也提供一些方法來操作列表,例如 append 方法可以在列表的末尾添加元素:

>>> t = ['a', 'b', 'c']
>>> t.append('d')
>>> t
['a', 'b', 'c', 'd']

extend 方法可以一次附加所有元素:

>>> t1 = ['a', 'b', 'c']
>>> t2 = ['d', 'e']
>>> t1.extend(t2)
>>> t1
['a', 'b', 'c', 'd', 'e']
>>> t3 = [4, 5, 6]
>>> t1.append(t3)
>>> t1
['a', 'b', 'c', 'd', 'e', [4, 5, 6]]

上例中,有兩點需要注意:

  • t2 與 t3 的內容不會被修改。
  • extend 與 append 的追加元素方式不同,extend 會展開所有元素再添加,append 是有什麼就加什麼。

下面的例子將列表的元素字母順序重新順向排列:

>>> t = ['d', 'c', 'e', 'b', 'a']
>>> t.sort()
>>> t
['a', 'b', 'c', 'd', 'e']

注意,大部分列表的方法回傳值是 None ,雖然可能會對呼叫方法的列表產生影響,但不一定會回傳影響後的新列表,也就是只會作用在原列表上。

假設寫出 t1 = t.sort() ,那麼 t1 的值是 None,但 t 本身的列表是有變化的,如下範例:

>>> t = ['d', 'c', 'e', 'b', 'a']
>>> t1 = t.sort()
>>> t
['a', 'b', 'c', 'd', 'e']
>>> t1
# 沒東西,那確認型態:
>>> type(t1)
<class 'NoneType'>

10-7 映射、篩選與歸併

如果列表中的元素都是數字,要將所有數字相加,可以使用迴圈,像這樣:

def addAll(t):
	total = 0
	for x in t:
		total += x
	return total

grades = [90, 95, 97]
print(addAll(grades))
# 282

變數 total 預設值為 0, x 每次遍歷 t 列表中的一個元素,用 += 運算子可以快速地更新累加 x 到 total 上,這也稱為「累加器」或「計數器」。

將列表的元素相加是一種很常見的操作,所以 python 已經有內建的函數 sum 可以使用:

>>> t = [1, 2, 3]
>>> sum(t)
6

像這樣把多個元素組合成一個值,我們稱為歸併 reduce

建立一個列表時,可能會需要先遍歷另一個列表,下面的函數會將該列表中的英文單字的第一個字母轉成大寫,回傳成新字串列表:

def capitalizeAll(t):
	res = []
	for s in t:
		res.append(s.capitalize())
	return res

names = ['alice', 'John', '小明']
new_names = capitalizeAll(names)
print(new_names)
# ['Alice', 'John', '小明']

res 一開始是個空列表,每次迴圈都會把傳進來的參數字串的第一個字母轉成大寫,透過 append 方法來累加轉成大寫的字串給 res 這個列表。

所以 res 也可以說是一種累加器,像 capitalizeAll 這種函數的做法,也被稱為映射 map 函數,因為它把一個個元素映射到新的列表當中。

注意,從上例中可以看出兩點:

  • 有中文字也不會報錯,就只是不轉換而已。
  • capitalize 方法是將首字母轉為大寫,同時將非首字母的大寫轉為小寫。

還有一種情況是只挑選出列表的某些元素,做了某些事情後將其返回。像是下面的例子,這個函數接受一個列表,但它只返回列表元素字串中含有全部大寫的字串元素:

def onlyUpper(t):
	res = []
	for s in t:
		if s.isupper():
			res.append(s)
	return res

fruits = ['apple', 'BANANA', 'orange']
new_fruits = onlyUpper(fruits)
print(new_fruits)
# ['BANANA']

像上面這種情況,我們稱為篩選或過濾 filter ,並非把所有的元素返回,而是透過判斷式,只回傳符合條件的部分,近似於過濾機制。

經由上面這些例子可總結出,經常操作列表的動作,就是映射、篩選與歸併這些行為。

10-8 刪除列表元素

這裡有一些刪除列表元素的方式,若較為熟悉列表的索引操作,可以選擇 pop 方法:

>>> t = ['a', 'b', 'c']
>>> x = t.pop(1)
>>> t
['a', 'c']
>>> x
'b'

pop 方法改變了列表的元素,刪除位於索引 1 的元素,也就是 'b' ,並且回傳被刪除的元素 'b' 給變數 x。

如果不提供索引給 pop 當作參數的話,預設就是刪除列表的最後一個元素。

如果不需要回傳刪除的值,那可以使用 del 關鍵字來刪除。當然,不接 pop 的回傳值,也不會發生錯誤:

>>> t = ['a', 'b', 'c']
>>> del t[1]
>>> t
['a', 'c']

del 還可以刪除整個變數:

>>> t = ['a', 'b', 'c']
del t
>>> t
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 't' is not defined
# 因為 t 整個刪除了,所以顯示 t 沒有被定義的錯誤訊息

如果知道想要刪除的元素內容,卻不知道其索引,那可以使用 remove 方法:

>>> t = ['a', 'b', 'c']
>>> t.remove('b')
>>> t
['a', 'c']

remove 沒有回傳值,或者說回傳 None,直接指定元素內容是較直覺的方式。若有相同元素的內容,只會刪除索引較前面的那個元素。

如果想刪除一個以上的元素,可以使用 del 搭配索引切片:

>>> t = ['a', 'b', 'c', 'd', 'e', 'f']
>>> del t[1:5]
>>> t
['a', 'f']

與之前介紹過的切片一樣,切片選擇的範圍是第一個索引到第二個索引減一的值。

10-9 列表與字串

字串是由字元所構成的序列,列表是由不同型態的值所組成的序列。

兩者還是不太一樣,如果想把字串以字元的方式轉換成列表,可以使用 list 這個函數:

>>> s = 'spam'
>>> t = list(s)
>>> t
['s', 'p', 'a', 'm']

字串的每個字元都變成列表的一個元素。因為 list 是內建的函數,所以避免使用這個名稱來當作變數。順帶一提,也避免使用 l,螢幕上看起來長得太像 1 或 I 了。

如果想以整個單字的方式把字串轉成列表,可以使用 split 方法來完成:

>>> s = 'pining for the fjords'
>>> t = s.split()
>>> t
['pining', 'for', 'the', 'fjords']

上例省略了 split 的參數,表示使用空格來對字串切割,可以自己指定切割符號,例如短橫線,也就是 dash,依據字串內容決定即可:

>>> s = 'spam-spam-spam'
>>> delimiter = '-'
>>> t = s.split(delimiter)
>>> t
['spam', 'spam', 'spam']

join 的功能跟 split 相反,以 delimiter 變數的內容連接列表的元素成為一個字串,所以 join 的參數是一個列表:

>>> t = ['pining', 'for', 'the', 'fjords']
>>> delimiter = ' '
>>> s = delimiter.join(t)
>>> s
'pining for the fjords'

上面的例子是使用空格當作連接兩個元素間的符號,可以使用空字串 '' 這樣就會把列表全部組合成一個字串。

10-10 物件和值

如果執行這些敘述:

a = 'banana'
b = 'banana'

如上例,a 和 b 都是指向一個字串,但我們不知道它們到底是不是同一個字串,這裡可能會有兩種情形:

  • a 和 b 參考了兩個不同的物件,但這兩個物件剛好擁有相同的值。
  • 它們參考的是相同的物件。

想要檢查是不是同一個物件,可以使用 is 這個運算子來確認:

>>> a = 'banana'
>>> b = 'banana'
>>> a is b
True
>>> a == b
True

從上面的例子可以看出 python 實際上只創建了一個字串物件 'banana',然後讓 a 和 b 去指向它。

但因為字串特性是無法變更,所以這兩個字串不會相互影響。

如果創建了兩個列表,那麼得到的是兩個不同物件:

>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> a is b
False
>>> a == b
True

在上面的情況,這兩個列表是相等的 equivalent, 因為它們擁有一樣的元素,但他們不完全相同 identical,

如果它們相同則一定相等,但只是相等卻不一定相同。由於是不同物件,所以元素內容改變並不影響彼此:

>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> a[0] = 10
>>> a
[10, 2, 3]
>>> b
[1, 2, 3]

為了快速進入列表章節,一開始我們沒有仔細地區分物件和值,如果有一個列表為 [1, 2, 3],這就是一個含有整數值的列表物件。

當有另外一個列表的值也是 1, 2, 3 那我們可以說這兩個列表擁有相同的值,但它們是不同的物件。

如果兩個元素是相同的物件,被操作時就會相互影響:

>>> a = [1, 2, 3]
>>> b = a
>>> a is b
True
>>> a == b
True
>>> a[0] = 10
>>> a
[10, 2, 3]
>>> b
[10, 2, 3]

因此在處理列表時需要流意是否為相同元件,元件相同時的值會相互影響。

10-11 別名

對於上一節的最後一個例子,如果 a 參考了一個物件,而 b = a ,則這兩個變數是參考了同一個物件。

變數與物件的關係稱為參考或引用,在上面的例子就是兩個變數參考到同一個物件。

一個物件可以被很多名字參考,物件可以具有多個別名。如果物件別名是可變的,那麼變更別名也會影響到其他別名。

雖然這樣看起來似乎很方便,卻容易發生錯誤,所以儘量避免可變的物件使用多個相同別名。

10-12 列表參數

當列表作為函數的參數時,在函數中改變列表也會直接作用在原列表上。

如下例,刪除了列表的第一個元素:

def deleteHead(t):
	del t[0]

以下是這個函數的用法:

>>> letters = ['a', 'b', 'c']
>>> deleteHead(letters)
>>> letters
['b', 'c']

因為函數的參數 t 與變數 letters 是別名的關係,也就是指向同一個物件,雖然上例並沒有回傳刪除後的新列表,但實際上已經影響了原列表。

弄清楚一個動作到底是修改列表還是創建一個新列表非常重要,像是 append 方法是修改,而加號 + 運算子則是創建,以下是 append 的例子:

>>> t1 = [1, 2]
>>> t2 = t1.append(3)
>>> t1
[1, 2, 3]
>>> t2
None

append 本身沒有回傳值,所以 t2 就變成 None 了。接下來是加號運算子的例子:

>>> t1 = [1, 2, 3]
>>> t3 = t1 + [4]
>>> t1
[1, 2, 3]
>>> t3
[1, 2, 3, 4]

因為加號 + 會創建一個新的列表,使用等號來獲取新列表,而加號左邊的原列表並不會有所變動,這與變數的運算相同。

當撰寫一個修改列表的函數時,有些地方需要注意,例如下面的例子,它並不會真的刪除原列表的第一個元素:

def badDeleteHead(t):
	t = t[1:] # 錯誤
	print(t) # 僅限在函數內有作用

雖然切片創建的新列表給 t 參考,但它並不會作用在原列表:

>>> t4 = [1, 2, 3]
>>> badDeleteHead(t4)
>>> t4
[1, 2, 3]
>>> t4 = badDeleteHead(t4)
>>> t4
None
# 因為該函數沒有回傳 t ,所以拿到的是 None

在上面的函數中, t 得到的是一個新列表,所以原列表 t4 並沒有被更動。

另外一個方式是撰寫一個函數,直接把想要的最後列表結果回傳回去,這樣就有差別了:

def tail(t):
	return t[1:]

這樣也可以成功讓原列表指向一個新列表,以下是它的用法:

>>> letters = ['a', 'b', 'c']
>>> rest = tail(letters)
>>> rest
['b', 'c']

上面的函數避免了 letters 被參考改動的狀況,且又可以拿到想要的結果列表。

由以上這些例子的結果,簡單整理結論如下:

  • 只要是直接變更列表元素,就算是在函數內運作,也會影響函數外原列表。
  • 如果方法是在函數內另外創建一個新列表,則在函數外的原列表不受影響。

函數內的列表都是會變更的,差別就在於函數外的原列表會不會跟著異動而已。

10-13 列表的方法整理

  1. append() 向列表後方添加元素
  2. clear() 清空列表中的元素
  3. copy() 複製一份列表
  4. count() 計算該元素出現在列表的次數
  5. extend() 將元素展開並放置於列表之後,就是向列表後方添加多個元素,被添加的元素們由另一個列表來指定
  6. index() 回傳該元素第一次出現在列表的索引值
  7. insert() 指定索引插入元素於列表中
  8. pop() 使用索引來刪除列表中的元素
  9. remove() 使用元素值來刪除列表中的某個元素
  10. reverse() 將列表元素位置的順序反轉
  11. sort() 將列表的元素值進行排序

除錯

使用像列表這種可變物件時要小心,請留意以下的原則:

  1. 多數的列表方法會直接變更列表裡的元素而回傳 None, 這與字串的方法不同,字串方法通常會產生一個新字串並回傳而保留原字串。
    通常字串方法會這樣使用: word = word.strip()
    所以在使用列表方法時,可能也會這樣寫: t = t.sort()
    但因為 sort() 返回 None , t 就變成 None 了,之後的相關操作都會失敗或錯誤。
    所以在使用列表方法時必須小心,看清楚手冊,並在交互模式下測試,以確保結果正確。

  2. 選擇一種方法並貫徹它。
    列表有個特色,就是能以很多方法達成同一件要求,這是優點也是缺點。像是刪除列表中的元素,可以用 pop, remove 與 del 等;新增元素,可以用 insert, append 與 + 等。
    現在假設 t 是列表,而 x 是想添加到列表的元素,以下的寫法都是正確的:

t.append(x)
t += [x]

而以下寫法都是錯的,或無效的:

t = t.append(x)
t + [x]

使用交互模式測試,確定了解這些是在做什麼,不良做法在語法上都是正確的,但結果不會是我們想要的,觀念必須正確。

  1. 複製一份以避免混淆。
    假設想重新排序列表,但又希望保持原列表,可以選擇複製一份來操作:
>>> t = [3, 1, 2]
>>> t2 = t[:]
>>> t2.sort()
>>> t
[3, 1, 2]
>>> t2
[1, 2, 3]
在這個例子中,還有一個方法是使用內建函數 sorted() 來達成,它不會改變原本列表的順序,而是回傳一個新列表:
>>> t = [3, 1, 2]
>>> t2 = sorted(t)
>>> t
[3, 1, 2]
>>> t2
[1, 2, 3]
  1. 在操作列表時難免會發生 IndexError 的狀況,就是索引值超過了列表。
    很有可能是算錯,忘記列表是從 0 開始計算的。可以使用兩個方法來除錯:

    • 使用 len() 函數來計算列表共有多少個元素。
    • 使用索引 -1 來印出該列表的最後一個元素,進行確認。

動動腦

  1. 寫一小段程式,目的是確保該列表沒有該值才添加進去
students = ['小芸', '小蓉', '小良', '小慶', '小恩']
student = '小蓉'

if student not in students:
	students.append(student)
	print(student, '加入群組')
else:
	print(student, '已經在群組中了')

print('以下是目前群組中的成員')
for student in students:
	print(student)
  1. 已經知道有好幾種方式可以刪除列表的元素,若想要一次刪除相同的元素值,該怎麼做 (不能用切片)?
letters = ['a', 'b', 'c', 'd', 'd', 'c', 'b', 'a']
del_letter = 'c'

while True:
	if del_letter in letters:
		letters.remove(del_letter)
		print(del_letter, '被刪除了')
		continue
	else:
		break

print('字母列表:', letters)
  1. 使用 clear() 方法可以清空列表,那它跟 del 有什麼不同?

clear() 是列表方法,只能用在列表。
del 是 python 指令關鍵字,適用所有型態元素,並且可從記憶體中刪除整個變數。

練習

第1題 檔名: 10-1.py

寫一個函數名為 nestedSum, 將巢狀列表中的所有元素加起來並輸出,如下:

>>> t = [[1, 2], [3], [4, 5, 6]]
>>> nested_sum(t)
21
第2題 檔名: 10-2.py

寫一個函數名為 cumSum, 將列表中的元素從第一個元素開始加到所有元素的和,產生一個新列表,列表的元素就是每一項的和,如下:

>>> t = [1, 2, 3]
>>> cumSum(t)
[1, 3, 6]
>>> t = [2, 4, 5, 1]
>>> cumSum(t)
[2, 6, 11, 12]
第3題 檔名: 10-3.py

寫一個函數名為 middle, 輸出一個新列表,該列表不包含原列表的最前與最後元素,如下:

>>> t = [1, 2, 3, 4]
>>> middle(t)
[2, 3]
第4題 檔名: 10-4.py

寫一個函數名為 chop, 帶入一個列表的最前與最後一個元素刪除並返回 None, 如下:

>>> t = [1, 2, 3, 4]
>>> q = chop(t)
>>> t
[2, 3]
>>> q
None
第5題 檔名: 10-5.py

寫一個函數名為 isSorted, 回傳 True 表示該列表已經由小到大排列,反之則回傳 False, 如下:

>>> isSorted([1, 2, 2])
True
>>> isSorted(['b', 'a'])
False
>>> isSorted([2, 4, 8, 7])
False
>>> isSorted([3, 10, 20, 99, 101])
True
第6題 檔名: 10-6.py

寫一個函數名為 isAnagram, 它有兩個字串參數,當這兩個字串互為字謎時回傳 True, 反之回傳 False,如下:

>>> isAnagram('good', 'look')
False
>>> isAnagram('good', 'doog')
True
>>> isAnagram('way', 'yaw')
True
第7題 檔名: 10-7.py

寫一個函數名為 hasDuplicates, 接受一個列表參數,如果列表的元素有重複出現就回傳 True, 反之回傳 False,不能更動到原列表,如下:

>>> t = [3, 7, 5, 7, 9]
>>> hasDuplicates(t)
True
>>> t
[3, 7, 5, 7, 9]
>>> t = ['abc', 'def', 5, 7, 'ab']
>>> hasDuplicates(t)
False
>>> t
['abc', 'def', 5, 7, 'ab']
第8題 檔名: 10-8.py

寫一個函數名為 addList, 功能是讀取 words.txt 檔的單字並寫進新列表中,參數是檔名,回傳一個列表。

使用兩種方式,也就是兩個版本,分別是 t.append(w)t = t + [w], 測試看看哪一種方式比較快,為什麼?

如果 words.txt 內容太多,可以先使用幾個單字來測試即可。

第9題 檔名: 10-9.py

寫一個函數名為 wordSearch, 來做二分搜尋法,參數是列表與想查找的元素值,如果找到該元素的索引位置就回傳,沒找到就回傳 -1, 可以 words.txt 為例來查找,或者利用上個習題的結果查找某個單字。

提示:二分搜尋法是把 已排序 的資料對半分,查找的值小於中間值就找左半邊,大於則找右半邊,接著再把資料對半分,直到找到或找完為止。

>>> wl = addList('words.txt')
>>> wordSearch(wl, 'good')
41878
第10題 檔名: 10-10.py

利用之前習題與寫過的函數,寫一個函數名為 palindrome, 列出 words.txt 有哪些回文單字

dog, god
...

參考資料

map教學

map filter reduce 參考資料

最後更新:2021-07-18 11:23:12

From: 111.249.156.141

By: 特種兵