Python实用技法第17篇:将名称映射到序列的元素中

作者: IT派森 | 来源:发表于2019-08-22 19:09 被阅读2次

1、需求

我们的代码是通过位置(即索引或下标)来访问列表会元组的,但有时候这会让代码变得有些难以阅读。我们希望可以通过名称来访问元素,以此减少结构中对位置的依赖性。

2、解决方案

相比普通的元组,collections.namedtuple()(命名元组)只增加了极少的开销就提供了这些便利。实际上collections.namedtuple()是一个工厂方法,它返回的是Python中标准元组类型的子类。我们提供给它一个类型名称以及相应的字段,它就返回一个可实例化的类、为你已经定义好的字段传入值等。

from collections import namedtuple
Subscriber=namedtuple('Subsciber',['addr','joined'])
sub=Subscriber("1782980833@qq.com","2018-10-23")

print(sub)
print(sub.addr)
print(sub.joined)

print(len(sub))
addr,joined=sub
print(addr)
print(joined)

#下面错误,因为namedtuple是不可变的
#sub.joined="2019"
Python资源分享qun 784758214 ,内有安装包,PDF,学习视频,这里是Python学习者的聚集地,零基础,进阶,都欢迎

结果:

Subsciber(addr='1782980833@qq.com', joined='2018-10-23')
1782980833@qq.com
2018-10-23
2
1782980833@qq.com
2018-10-23

尽管namedtuple的实例看起来就像一个普通的类实例,但它的实例与普通的元组是可互换的,而且支持所有普通元组所支持的操作。

命名元组的主要作用在于将代码同它所控制的元素位置间解耦。所以,如果从数据库调用中得到了一个大型的元组列表,而且通过元素的位置来访问元素,那么假如在表单中新增了一列数据,那么代码就会崩溃,但如果首先将返回的元组转换为命名元组,就不会出现问题。

为了说明这个问题,下面有一些使用普通元组的代码:

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

3、分析

namedtuple的一种可能用法是作为字典的替代,后者需要更多的空间来存储。因此,如果要构建设计字典的大型数据,使用namedtuple会更加高效,但是请注意,与字典不同的是,namedtuple是不可变的。

如果需要修改任何属性,可以通过使用namedtuple实例_replace()方法来实现。该方法会创建一个全新的命名元组,并对相应的值做替换。

from collections import namedtuple
Subscriber=namedtuple('Subsciber',['addr','joined'])
sub=Subscriber("1782980833@qq.com","2018-10-23")

print(sub)

sub=sub._replace(joined="2018-10-24")
print(sub)

结果:

Subsciber(addr='1782980833@qq.com', joined='2018-10-23')
Subsciber(addr='1782980833@qq.com', joined='2018-10-24')

_replace()方法有一个微妙的用途,那就是它可以作为一种简单的方法填充具有可选或缺失字段的命名元组。要做到这点,首先创建一个包含默认值得原型数组,然后使用_replace()方法创建一个新的实例,把相应的值替换掉。

from collections import namedtuple
Subscriber=namedtuple('Subsciber',['addr','joined','age'])
sub=Subscriber("",None,0)

def dict_to_stock(s):
    return sub._replace(**s)

a={"addr":"111111@qq.com","joined":"1111-11-11","age":11}
a=dict_to_stock(a)
print(a)

b={"addr":"111111@qq.com","joined":"1111-11-11"}
b=dict_to_stock(b)
print(b)

结果:

Subsciber(addr='111111@qq.com', joined='1111-11-11', age=11)
Subsciber(addr='111111@qq.com', joined='1111-11-11', age=0)
Python资源分享qun 784758214 ,内有安装包,PDF,学习视频,这里是Python学习者的聚集地,零基础,进阶,都欢迎

最后,也是相当重要的是,应该要注意如果我们的目标是定义一个高效的数据结构,而且将来会修改各种实例属性,那么使用namedtuple并不是最佳选择,相反,可以考虑顶一个使用了slots属性的类。

相关文章

  • Python实用技法第17篇:将名称映射到序列的元素中

    1、需求 我们的代码是通过位置(即索引或下标)来访问列表会元组的,但有时候这会让代码变得有些难以阅读。我们希望可以...

  • Python学习路线实用技法:筛选序列中的元素

    Python学习路线实用技法:筛选序列中的元素 序列中含有一些数据,我们需要提取其中的值或根据某些标准对序列做删减...

  • Python实用技法第15篇:筛选序列中的元素

    1、需求? 序列中含有一些数据,我们需要提取其中的值或根据某些标准对序列做删减, 2、解决方案? 要筛选序列中的数...

  • python 学习笔记:将名称映射到序列中

    问题 通过名称来访问元素,减少结构中对位置的依赖性 解决方案 collections.namedtuple()——...

  • python 基础 - 列表

    Python 列表 序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置,或索引,第...

  • Python 映射名称到序列元素

    映射名称到序列元素 一般访问列表或者元组的元素的时候,可能有限考虑的是通过下标索引进行访问,但是有些时候,这种情况...

  • 元素操作符

    First:返回序列中的第一个元素;如果是空序列,此方法将引发异常。 FirstOrDefault:返回序列中的第...

  • python - Lists

    2018-05-07 python - Lists Python中最基本的数据结构是序列。序列中的每个元素都被分配...

  • 8、Python 序列

    一、概要 在Python中,最基本的数据结构是序列(sequence)。序列中的每个元素被分配一个序号——即元素的...

  • Python知识

    在Python中,最基本的数据结构是序列(sequence)。序列中的每个元素被分配一个序号——即元素的位置,也称...

网友评论

    本文标题:Python实用技法第17篇:将名称映射到序列的元素中

    本文链接:https://www.haomeiwen.com/subject/wxuorctx.html