namedtuple是一个非常有趣(也被低估了)的数据结构。我们可以轻松找到严重依赖常规元组和字典来存储数据的Python代码。我并不是说,这样不好,只是有时候他们常常被滥用,且听我慢慢道来。

假设你有一个将字符串转换为颜色的函数。颜色必须在4维空间RGBA中表示。

def convert_string_to_color(desc: str, alpha: float = 0.0):if desc == "green":return 50, 205, 50, alphaelif desc == "blue":return 0, 0, 255, alphaelse:return 0, 0, 0, alpha
复制代码

然后,我们可以像这样使用它:

r, g, b, a = convert_string_to_color(desc="blue", alpha=1.0)
复制代码

好的,可以。但是我们这里有几个问题。第一个是,无法确保返回值的顺序。也就是说,没有什么可以阻止其他开发者这样调用

convert_string_to_color:
g, b, r, a = convert_string_to_color(desc="blue", alpha=1.0)
复制代码

另外,我们可能不知道该函数返回4个值,可能会这样调用该函数:

r, g, b = convert_string_to_color(desc="blue", alpha=1.0)
复制代码

于是,因为返回值不够,抛出ValueError错误,调用失败。

确实如此。但是,你可能会问,为什么不使用字典呢?

Python的字典是一种非常通用的数据结构。它们是一种存储多个值的简便方法。但是,字典并非没有缺点。由于其灵活性,字典很容易被滥用。让 我们看看使用字典之后的例子。

def convert_string_to_color(desc: str, alpha: float = 0.0):if desc == "green":return {"r": 50, "g": 205, "b": 50, "alpha": alpha}elif desc == "blue":return {"r": 0, "g": 0, "b": 255, "alpha": alpha}else:return {"r": 0, "g": 0, "b": 0, "alpha": alpha}
复制代码

好的,我们现在可以像这样使用它,期望只返回一个值:

color = convert_string_to_color(desc="blue", alpha=1.0)
复制代码

无需记住顺序,但它至少有两个缺点。第一个是我们必须跟踪密钥的名称。如果我们将其更改{"r": 0, “g”: 0, “b”: 0, “alpha”: alpha}为{”red": 0, “green”: 0, “blue”: 0, “a”: alpha},则在访问字段时会得到KeyError返回,因为键r,g,b和alpha不再存在。

字典的第二个问题是它们不可散列。这意味着我们无法将它们存储在set或其他字典中。假设我们要跟踪特定图像有多少种颜色。如果我们使用collections.Counter计数,我们将得到TypeError: unhashable type: ‘dict’。

而且,字典是可变的,因此我们可以根据需要添加任意数量的新键。相信我,这是一些很难发现的令人讨厌的错误点。

好的,很好。那么现在怎么办?我可以用什么代替呢?

namedtuple!对,就是它!

将我们的函数转换为使用namedtuple:

from collections import namedtuple
...
Color = namedtuple("Color", "r g b alpha")
...
def convert_string_to_color(desc: str, alpha: float = 0.0):if desc == "green":return Color(r=50, g=205, b=50, alpha=alpha)elif desc == "blue":return Color(r=50, g=0, b=255, alpha=alpha)else:return Color(r=50, g=0, b=0, alpha=alpha)复制代码

与dict的情况一样,我们可以将值分配给单个变量并根据需要使用。无需记住顺序。而且,如果你使用的是诸如PyCharm和VSCode之类的IDE ,还可以自动提示补全。

color = convert_string_to_color(desc="blue", alpha=1.0)
...
has_alpha = color.alpha > 0.0
...
is_black = color.r == 0 and color.g == 0 and color.b == 0
复制代码

最重要的是namedtuple是不可变的。如果团队中的另一位开发人员认为在运行时添加新字段是个好主意,则该程序将报错。

>>> blue = Color(r=0, g=0, b=255, alpha=1.0)>>> blue.e = 0
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-13-8c7f9b29c633> in <module>
----> 1 blue.e = 0AttributeError: 'Color' object has no attribute 'e'
复制代码

不仅如此,现在我们可以使用它Counter来跟踪一个集合有多少种颜色。

>>> Counter([blue, blue])
>>> Counter({Color(r=0, g=0, b=255, alpha=1.0): 2})
复制代码

为什么要使用namedtuple?相关推荐

  1. Python collections 模块 namedtuple、Counter、defaultdict

    1. namedtuple 假设有两个列表,如下,要判断两个列表中的某一个索引值是否相等. In [7]: p = ['001', 'wohu', '100', 'Shaanxi']In [8]: t ...

  2. python namedtuple用法_Python的collections模块中namedtuple结构使用示例

    namedtuple 就是命名的 tuple,比较像 C 语言中 struct.一般情况下的 tuple 是 (item1, item2, item3,...),所有的 item 都只能按照 inde ...

  3. python3 namedtuple_你不能低估的Python数据结构Namedtuple(二)

    上篇你不能低估的Python数据结构Namedtuple(一)讲了namedtuple的一些基本用法,本篇继续. namedtuples和数据类(Data Class)之间有什么区别? 功能 在Pyt ...

  4. python中typing.NamedTuple示例

    python中typing.NamedTuple示例 from typing import * # 导入依赖项 class Friend(NamedTuple): """ ...

  5. python namedtuple用法_Python namedtuple(命名元组)使用实例

    namedtuple对象就如它的名字说定义的那样,你可以给tuple命名,具体看下面的例子:import collections Person=collections.namedtuple('Pers ...

  6. Python defaultdict 模块和 namedtuple 模块

    在Python中有一些内置的数据类型,比如int, str, list, tuple, dict等.Python的collections模块在这些内置数据类型的基础上,提供了几个额外的数据类型:nam ...

  7. python 库整理: collections.namedtuple

    namedtuple创建一个和tuple类似的对象,而且对象拥有可访问的属性. 1 nametuple的创建 User1 = namedtuple('User_name', ['name', 'sex ...

  8. Python defaultdict 模块和 namedtuple 模块 1

    在Python中有一些内置的数据类型,比如int, str, list, tuple, dict等.Python的collections模块在这些内置数据类型的基础上,提供了几个额外的数据类型:nam ...

  9. pythonnamedtuple定义类型_详解Python中namedtuple的使用

    namedtuple是Python中存储数据类型,比较常见的数据类型还有有list和tuple数据类型.相比于list,tuple中的元素不可修改,在映射中可以当键使用. namedtuple: na ...

  10. Python中比元组更好用的namedtuple

    1.什么是元组? 不可变的序列类型 "不能修改的列表" 2.元组支持哪些操作? 元组是序列类型,支持序列类型的所有操作 通过索引取值 one_tuple = ("可优&q ...

最新文章

  1. 64 os 驱动签名
  2. SpringBoot rest映射及源码解析
  3. 为您的机器配置开发环境
  4. 自动生成sqlserver增删改成_如何批量生成证书证件-可变条码-可变图片-可变数据-快速教程...
  5. PDH光端机常见故障问题解决方法
  6. VS2017注册之找不到输入key的地方的解决方法
  7. PLC通过控制器控制步进电机
  8. h30-t10 android phone,荣耀3C移动2G版(H30-T10)官方完整版ROM全合集!!!
  9. python多边形的绘制教程_使用Python matplotlib绘制3D多边形
  10. [生存志] 第51节 子产相郑铸刑书
  11. 华信云SMS短信平台介绍
  12. Java实现 蓝桥杯 算法提高 矩阵翻转
  13. 分析了网易云数十万歌单后写出2020年的最全歌单推荐
  14. 坑逼的PL2303与WIN11
  15. secureCRT连接阿里云服务器
  16. C语言中%s,%m.ns 和 %e,%m.ne 的意思
  17. ping 域名显示 Ping request could not find host 但是nsloo
  18. 无代码开发工具推荐丨三叠云
  19. git 强行拉取覆盖本地
  20. vue+php使用七牛云存储解决富文本图片冗余问题

热门文章

  1. x86汇编语言(2) 认识8086处理器
  2. mysql中select后接数字_MySQL SELECT用于从一组数字中排列一个数字
  3. python 判断是否连接wifi_python操作 linux连接wifi,查看wifi连接状态方法
  4. android嵌入式面试题,嵌入式软件面试题 经典笔试题(含答案)
  5. string字符串转实体类_【Recursion】(6)实战练习:使用递归处理字符串
  6. 心得 | 《用得上的商学课》 004 边际成本 | 飞机起飞前的座位,只卖一块钱?...
  7. Django 框架篇(七) : 中间件 以及 5种方法
  8. java打印条形码Code128C
  9. baidu 地图 鼠标移上显示标签 鼠标离开隐藏标签
  10. SSL 1105——【USACO 2.1】顺序的分数(递归+二分)