- Python進階編程:編寫更高效、優雅的Python代碼
- 劉宇宙 謝東 劉艷
- 836字
- 2021-04-30 12:39:43
3.1.6 序列元素名稱映射
對于很多初學者來說,訪問列表或元組時習慣使用下標,這樣編寫的代碼不但可讀性差,而且可維護性差。建議使用更優雅的方式實現,比如通過名稱訪問。
collections.namedtuple()函數通過使用一個普通的元組對象來解決這個問題。實際上,該函數是一個返回Python中標準元組類型的子類的工廠函數,給它傳遞一個類型名和需要的字段,會返回一個類。初始化這個類可以為定義的字段傳遞值,示例如下:
from collections import namedtuple UserInfo = namedtuple('UserInfo', ['email', 'date']) user_info = UserInfo('test@ai.com', '2012-10-19') print(user_info) print(user_info.email) print(user_info.date)
盡管namedtuple實例看起來像一個普通的類實例,但它與元組類型是可交換的,支持所有的普通元組操作,如索引和解壓,示例如下:
print(len(user_info)) email, date = user_info print(email, date)
命名元組的一個主要用途是將代碼從下標操作中解脫出來。
如果從數據庫調用中返回一個很大的元組列表,我們可通過下標去操作其中的元素。當在普通元組列表中添加新的列的時候,代碼可能會出錯。但若使用了命名元組,則不會有這樣的顧慮。
先看使用普通元組的代碼示例:
def calculate_cost_1(record_list): total = 0.0 for record in record_list: total += record[1] * record[2] return total
下標操作通常會讓代碼表意不清晰,并且非常依賴記錄的結構。更改為使用命名元組的示例如下:
from collections import namedtuple Course = namedtuple('Course', ['name', 'class_hour', 'score']) def calculate_cost(record_list): total = 0.0 for rec in record_list: course = Course(*rec) total += course.class_hour * course.score return total
命名元組另一個用途是作為字典的替代,因為字典存儲需要更多的內存空間。如果需要構建一個非常大的包含字典的數據結構,那么使用命名元組會更加高效。
注意 命名元組是不可更改的。
如果需要改變屬性值,那么可以使用命名元組實例的_replace()方法。它會創建一個全新的命名元組并將對應的字段用新的值取代,示例如下:
course = Course('xiao meng', 20, 0.3) print(course) course = course._replace(class_hour=30) print(course)
當命名元組擁有可選或者缺失字段時,_replace()方法是一個非常方便的填充數據的方法。首先創建一個包含缺省值的原型元組,然后使用_replace()方法創建新的值被更新過的實例,示例如下:
from collections import namedtuple Course = namedtuple('Course', ['name', 'class_hour', 'score', 'date', 'time']) # Create a prototype instance course_prototype = Course('', 0, 0.0, None, None) # Function to convert a dictionary to a Course def dict_to_course(course): return course_prototype._replace(**course)
上述定義的dict_to_course()函數的使用方式如下(list_mapping_exp.py):
course_a = {'name': 'xiao meng', 'class_hour': 20, 'score': 0.3} print(dict_to_course(course_a)) course_b = {'name': 'xiao meng', 'class_hour': 20, 'score': 0.3, 'date': '04/19/2020'} print(dict_to_course(course_b))
如果目標是定義一個需要更新很多實例屬性的高效的數據結構,那么命名元組并不是最佳選擇,這時候應該考慮定義一個包含__slots__方法的類。
- Java入門經典(第6版)
- SQL學習指南(第3版)
- Learning RxJava
- Building a Recommendation Engine with Scala
- Python高效開發實戰:Django、Tornado、Flask、Twisted(第3版)
- Hands-On Microservices with Kotlin
- 學Python也可以這么有趣
- 從0到1:Python數據分析
- SQL Server從入門到精通(第3版)
- Python數據結構與算法(視頻教學版)
- Python Data Structures and Algorithms
- 利用Python進行數據分析
- Python Interviews
- Image Processing with ImageJ
- Serverless Web Applications with React and Firebase