官术网_书友最值得收藏!

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__方法的類。

主站蜘蛛池模板: 长汀县| 隆回县| 四川省| 封开县| 兴城市| 梁河县| 甘德县| 芜湖县| 兰州市| 曲阜市| 巫溪县| 长春市| 吕梁市| 呼和浩特市| 黔西县| 武隆县| 潢川县| 静海县| 苍梧县| 剑川县| 东阿县| 忻州市| 罗甸县| 平邑县| 中宁县| 无棣县| 简阳市| 萝北县| 周口市| 襄樊市| 连州市| 武定县| 方正县| 蓬安县| 济南市| 寿光市| 旬邑县| 武乡县| 姜堰市| 郴州市| 锦屏县|