內建函式 enumerate() 也是用來配對的, 但它是將傳入的序列型態物件 (元組, 串列, 字串) 與一組連續整數 (預設是 0 起始的整數) 配對成 tuple , 然後打包成 enumerate 物件傳回, 語法如下 :
enum=enumerate(序列 [, start=0])
可見 enumerate() 其實是簡單版的 zip() 函式, 瞭解 zip() 函式用法後再來看 enumerate() 就很容易理解, 它相當於是幫傳入的序列型態物件加上一組明確的連動索引, 這對資料處理很有用處. 關於 zip() 函式用法參考 :
enumerate 物件與 zip 物件一樣都是可迭代與迭代器物件, 可用 for 迴圈或 next() 函式走訪其元素 (為 tuple), 也可以用 list(), tuple(), 或 dict() 轉換成串列, 元組, 或字典. 但迭代器的特性是一旦被走訪完畢或被轉換成 tuple, list, 與 dict, 其內容將被清空, 無法第二次走訪或做轉換, 必須重新建立 enumerate 物件, 關於可迭代與迭代器參考 :
例如 :
>>> company=['台積電', '聯發科', '台塑']
>>> enum=enumerate(company) # 呼叫 enumerate() 做連續數值配對
>>> enum
<enumerate object at 0x0000024D07D4BC18>
>>> type(enum) # enumerate() 傳回 enumerate 物件
<class 'enumerate'>
>>> hasattr(enum, '__iter__') # enumerate 物件是可迭代物件
True
>>> hasattr(enum, '__next__') # enumerate 物件是迭代器物件
True
>>> for i in enum: # 用 for 迴圈走訪 enumerate 物件
print(i)
(0, '台積電')
(1, '聯發科')
(2, '台塑')
>>> list(enum) # 走訪後 enumerate 物件已清空
[]
>>> enum=enumerate(company) # 重新建立 enumerate 物件
>>> list(enum) # 轉成串列
[(0, '台積電'), (1, '聯發科'), (2, '台塑')]
>>> enum=enumerate(company) # 重新建立 enumerate 物件
>>> tuple(enum) # 轉成元組
((0, '台積電'), (1, '聯發科'), (2, '台塑'))
>>> tuple(enum) # 轉換後 enumerate 物件已清空
()
>>> enum=enumerate(company) # 重新建立 enumerate 物件
>>> dict(enum) # 轉成字典
{0: '台積電', 1: '聯發科', 2: '台塑'}
可見由於 enumerate() 是兩兩配對, 且配對時是以連續整數做為第一元素, 因此 enumerate 物件轉成字典完全沒有問題, 不像 zip() 因為可以將多個序列配對, 所以不一定能轉成字典 (兩兩配對時才能轉成字典), 而且可能有 key 重複問題.
enumerate() 預設是將序列中的元素與 0 起始的連續整數配對, 但也可以用 start 參數指定起始整數, 例如 :
>>> company=['台積電', '聯發科', '台塑', '玉山金', '統一超']
>>> enum=enumerate(company, start=10) # 用 index 參數指定起始整數
>>> list(enum)
[(10, '台積電'), (11, '聯發科'), (12, '台塑'), (13, '玉山金'), (14, '統一超')]
可見與序列元素配對的整數改為從 10 起算了. 這個 start 參數在資料處理上很實用, 例如有蠻多編號或索引系統是 1 起始.
使用 enumerate() 函式可以讓程式碼更簡潔, 更有 Python 風格 (Pythonic), 利用 enumerate 物件所配對的連續數值可用來做為關聯到其它序列資料的索引, 例如 :
>>> students=['Peter', 'Tony', 'Amy', 'Kelly']
>>> grades=[100, 95, 80, 92]
>>> for index, student in enumerate(students):
grade=grades[index]
print('Name:', student, 'Grade:', grade)
Name: Peter Grade: 100
Name: Tony Grade: 95
Name: Amy Grade: 80
Name: Kelly Grade: 92
此例將 students 序列傳入 enumerate() 做數值配對後, 利用走訪 enumerate 物件解包其 tuple 元素, 取得配對之索引與元素, 然後用此索引存取 grades 串列取得分數, 這種寫法具有 Python 的簡潔風格. 此例不使用 enumerate() 的寫法如下 :
>>> students=['Peter', 'Tony', 'Amy', 'Kelly']
>>> grades=[100, 95, 80, 92]
>>> for index in range(len(students)):
student=students[index] # 利用 [索引] 取值
grade=grades[index] # 利用 [索引] 取值
print('Name:', student, 'Grade:', grade)
Name: Peter Grade: 100
Name: Tony Grade: 95
Name: Amy Grade: 80
Name: Kelly Grade: 92
雖然也沒有很冗長, 但使用 len() 與 range() 套疊, 以及 [] 運算子取值就有點 "老實與樸拙".
沒有留言 :
張貼留言