Skip to content

Latest commit

 

History

History
61 lines (48 loc) · 2.09 KB

p18_map_names_to_sequences_elements.md

File metadata and controls

61 lines (48 loc) · 2.09 KB

1.18 映射名称到序列元素

问题

你有一段通过下标访问列表或者元组中元素的代码,但是这样有时候会使得你的代码难以阅读, 于是你想通过名称来访问元素。

解决方案

collections.namedtuple() 函数通过使用一个普通的元组对象来帮你解决这个问题。 这个函数实际上是一个返回 Python 中标准元组类型子类的一个工厂方法。 你需要传递一个类型名和你需要的字段给它,然后它就会返回一个类,你可以初始化这个类,为你定义的字段传递值等。 代码示例:

>>> from collections import namedtuple
>>> Subscriber = namedtuple('Subscriber', ['addr', 'joined'])
>>> sub = Subscriber('jonesy@example.com', '2012-10-19')
>>> sub
Subscriber(addr='jonesy@example.com', joined='2012-10-19')
>>> sub.addr
'jonesy@example.com'
>>> sub.joined
'2012-10-19'
>>>

尽管 namedtuple 的实例看起来像一个普通的类实例,但是它跟元组类型是可交换的,支持所有的普通元组操作,比如索引和解压。 比如:

>>> len(sub)
2
>>> addr, joined = sub
>>> addr
'jonesy@example.com'
>>> joined
'2012-10-19'
>>>

命名元组的一个主要用途是将你的代码从下标操作中解脱出来。 因此,如果你从数据库调用中返回了一个很大的元组列表,通过下标去操作其中的元素, 当你在表中添加了新的列的时候你的代码可能就会出错了。但是如果你使用了命名元组,那么就不会有这样的顾虑。

为了说明清楚,下面是使用普通元组的代码:

def compute_cost(records):
    total = 0.0
    for rec in records:
        total += rec[1] * rec[2]
    return total

下标操作通常会让代码表意不清晰,并且非常依赖记录的结构。 下面是使用命名元组的版本:

from collections import namedtuple

Stock = namedtuple('Stock', ['name', 'shares', 'price'])
def compute_cost(records):
    total = 0.0
    for rec in records:
        s = Stock(*rec)
        total += s.shares * s.price
    return total