課時13:元組:戴上了枷鎖的列表

那是個好男孩發表於2018-08-02

目錄:

    一、建立和訪問一個元組

    二、更新和刪除元組

    三、元組相關的操作符

    四、課時13課後習題及答案

 

由於和列表是近親關係,所以元組和列表在實際使用上是非常相似的。
我們這節課主要通過討論元組和列表到底有什麼不同來學習元組,醬紫大家就不會覺得老是重複一樣的內容。
我們主要從以下幾個點來討論學習:
---創鍵和訪問一個元組
---更新和刪除一個元組
---元組相關的操作符

*****************************

一、建立和訪問一個元組

*****************************

 元組和列表,除了不可改變這個顯著特徵以外,還有一個明顯的區別是,建立列表用的是中括號,而建立元組大部分用的是小括號(注意:我這裡說的是大部分)

>>> tuple1 = (1,2,3,4,5,6,7,8)
>>> tuple1
(1, 2, 3, 4, 5, 6, 7, 8)

訪問元組的方式與列表無異:

>>> tuple1[1]
2
>>> tuple1[5:]
(6, 7, 8)
>>> tuple1[:5]
(1, 2, 3, 4, 5)

也使用分片的方式來複制一個元組:

>>> tuple2 = tuple1[:]
>>> tuple2
(1, 2, 3, 4, 5, 6, 7, 8)

如果你試圖修改元組的一個元素,那麼抱歉,Python會很不開心:

>>> tuple1[1] = 1
Traceback (most recent call last):
  File "<pyshell#17>", line 1, in <module>
    tuple1[1] = 1
TypeError: 'tuple' object does not support item assignment

我很好奇的問你,列表的標誌性符號是中括號([ ]),那麼元組的標誌性符號是什麼?

這個問題其實大部分初學者所忽略和容易上當的:

>>> temp = (1)
>>> type(temp)
<class 'int'>

還記得type()方法吧,作用是返回引數的型別,這裡它返回說temp變數是整型int。再試試:

>>> temp = 1,2,3
>>> type(temp)
<class 'tuple'>

噢?發現了吧?就算沒有小括號,temp還是元組型別,所以逗號(,)才是關鍵,小括號只是起到補充的作用。但是你如果想要建立一個空元組,那麼你直接使用小括號即可:

>>> temp = ()
>>> type(temp)
<class 'tuple'>

所以這裡要注意的是,如果你要建立的元組中只有一個元素,請在它後邊加上一個逗號(,),這樣可以明確的告訴Python你要的是一個元組,不要拿什麼整型、浮點型來忽悠你:

>>> temp = (1)
>>> type(temp)
<class 'int'>
>>> temp2 = (1,)
>>> type(temp2)
<class 'tuple'>
>>> temp3 = 1,
>>> type(temp3)
<class 'tuple'>

為了證明逗號起到了關鍵性的作用,再舉個例子:

>>> 8 * (8)
64
>>> 8 * (8,)
(8, 8, 8, 8, 8, 8, 8, 8)

 

***********************

二、更新和刪除元組

***********************

 我們這裡討論的是一個相對含蓄的做法(直接在同一個元組上更新是不可行的,除非你學習了後面的"魔法方法"章節)。回想一下以前怎麼跟新字串的,是通過拷貝現有的字串片段構造一個新的字串的方式來解決的,對元組也是使用同樣的方法:

>>> temp = ("小雞","小鴨","小豬")
>>> temp = temp[:2] + ("小甲魚",)+temp[2:]
>>> temp
('小雞', '小鴨', '小甲魚', '小豬')

上面的程式碼需要在"小鴨""小豬"中間插入"小甲魚",那麼通過分片的方法讓元組拆分為兩部分,然後再使用連線操作符(+)合併成一個新元組,最後將原來的變數名temp指向連線好的新元組。不妨可以把這樣的做法稱為"狸貓換太子"。在這裡就要注意了,逗號是必須的,小括號也是必須的!

我們可以用剛才講的,間接的刪除一個元素:

>>> temp
('小雞', '小鴨', '小甲魚', '小豬')
>>> temp = temp[:2]+temp[3:]
>>> temp
('小雞', '小鴨', '小豬')

如果要刪除整個元組,只要使用del語句即可顯式地刪除一個元組:

>>> del temp
>>> temp
Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    temp
NameError: name 'temp' is not defined

其實在日常生活中,很少使用del去刪除整個元組,因為Python的回收機制會在這個元組不再被使用到的時候自動刪除。

**************************

三、元組相關的操作符

**************************

 最後小結一下哪些操作符可以使用在元組上,拼接操作符和重複操作符剛剛演示過了,關係操作符、邏輯操作符和成員操作符in 和not in 也可以直接應用在元組上,這跟列表是一樣的,大家實踐一下,就明白了。

********************************

四、課時13課後習題及答案

********************************

測試題:

0. 請用一句話描述什麼是列表?再用一句話描述什麼是元組?
1. 什麼情況下你需要使用元組而不是列表?
2. 當元組和列表掉下水,你會救誰?
3. 請將下圖左邊列表的內建方法與右邊的註釋連線,並圈出元組可以使用的方法。

4. 建立一個元組,什麼情況下逗號和小括號必須同時存在,缺一不可?
5. x, y, z = 1, 2, 3 請問x, y, z是元組嗎?
6. 請寫出以下情景中應該使用列表還是元組來儲存資料:

1) 遊戲中角色的屬性:
2) 你的身份證資訊:
3) 論壇的會員:
4) 團隊合作開發程式,傳遞給一個你並不瞭解具體實現的函式的引數:
5) 航天火箭各個元件的具體配置引數:
6) NASA系統中記錄已經發現的行星資料:

7. 上節課我們通過課後作業的形式學習到了“列表推導式”,那請問如果我把中括號改為小括號,會不會得到“元組推導式”呢?

 

答案:

測試題答案:

0. 請用一句話描述什麼是列表?再用一句話描述什麼是元組?
列表:一個大倉庫,你可以隨時往裡邊新增和刪除任何東西。
元組:封閉的列表,一旦定義,就不可改變(不能新增、刪除或修改)。
 
1. 什麼情況下你需要使用元組而不是列表?
當我們希望內容不被輕易改寫的時候,我們使用元組(把權力關進牢籠)。
當我們需要頻繁修改資料,我們使用列表。
 
2. 當元組和列表掉下水,你會救誰?
如果是我,我會救列表,因為列表提供了比元組更豐富的內建方法,這相當大的提高了程式設計的靈活性。
回頭來看下元組,元組固然安全,但元組一定建立就無法修改(除非通過新建一個元組來間接修改,但這就帶來了消耗),而我們人是經常搖擺不定的,所以元組只有在特殊的情況才用到,平時還是列表用的多。
綜上所述,小甲魚會救列表(列表是美眉)。
 
3. 請將左邊列表的內建方法與右邊的註釋連線,並圈出元組可以使用的方法。
 
看吧,元組果然比較悲劇吧,僅有兩個方法元組可以使用,其他方法都不行,不信你試試?
 

4. 建立一個元組,什麼情況下逗號和小括號必須同時存在,缺一不可?

在拼接只有一個元素的元組的時候,例如我們課上舉的例題:

>>> temp = (‘小甲魚’, ‘黑夜’, ‘迷途’, ‘小布丁’)
# 如果我想在“黑夜”和“迷途”之間插入“怡靜”,我們應該:
>>> temp = temp[:2] + (‘怡靜’,) + temp[2:]

 

5. x, y, z = 1, 2, 3 請問x, y, z是元組嗎?

所有的多物件的、逗號分隔的、沒有明確用符號定義的這些集合預設的型別都是元組,自己在IDLE中鍵入以下程式碼,並體會一下:

>>> x,y,z = 1,2,3
>>> type(x)
<class 'int'>
>>> h = x,y,z
>>> type(h)
<class 'tuple'>

 

6. 請寫出以下情景中應該使用列表還是元組來儲存資料:

1) 遊戲中角色的屬性:列表
  
2) 你的身份證資訊:元組
  
3) 論壇的會員:列表
  
4) 團隊合作開發程式,傳遞給一個你並不瞭解具體實現的函式的引數:元組
  
5) 航天火箭各個元件的具體配置引數:元組
  
6) NASA系統中記錄已經發現的行星資料:列表

 

7. 上節課我們通過課後作業的形式學習到了“列表推導式”,那請問如果我把中括號改為小括號,會不會得到“元組推導式”呢?自己動手試試看再看答案哦^_^

Python3 木有“元組推導式”,為嘛?沒必要丫,有了“列表推導式”已經足夠了。
那為什麼“>>> tuple1 = (x**2 for x in range(10))”不會報錯?
因為你誤打誤撞得到了一個生成器:

>>> type(tuple1)
<class 'generator'>

關於生成器的概念小甲魚今後會細講,你可以嘗試這麼去訪問我們剛剛的生成器:

# 注意,Python3 開始 next() 方法改為 __next__() ~

>>> tuple1.__next__()
0
>>> tuple1.__next__()
1
>>> tuple1.__next__()
4
>>> tuple1.__next__()
9
>>> tuple1.__next__()
16
>>> tuple1.__next__()
25
>>> tuple1.__next__()
36

 

 

 

 

 

 

 

 

 

 

 

相關文章