首先,我会介绍下使用namedtuple所需要了解的基本概念,然后讲解如何使用namedtuple,最后使用namedtuple来创建一摞纸牌。理解这些之后,就可以权衡利弊,并在生产中使用

基本概念

  1. namedtuple是一个 工厂函数,定义在python标准库的collections模块中,使用此函数可以创建一个可读性更强的元组
  2. namedtuple函数所创建(返回)的是一个 元组的子类(python中基本数据类型都是类,且可以在buildins模块中找到)
  3. namedtuple函数所创建元组,中文名称为 具名元组
  4. 在使用普通元组的时候,我们只能通过index来访问元组中的某个数据
  5. 使用具名元组,我们既可以使用index来访问,也可以使用具名元组中每个字段的名称来访问
  6. 值得注意的是,具名元组和普通元组所需要的内存空间相同,所以 不必使用性能来权衡是否使用具名元组

如何使用

namedtuple是一个函数,我们先来看下他的参数

参数解析

def namedtuple(typename, field_names, *, rename=False, defaults=None, module=None):
复制代码

有两个必填参数typenamefield_names typename

  • 参数类型为字符串
  • 具名元组返回一个元组子对象,我们要为这个对象命名,传入typename参数即可

field_names

  • 参数类型为字符串序列
  • 用于为创建的元组的每个元素命名,可以传入像['a', 'b']这样的序列,也可以传入'a b''a, b'这种被逗号空格分割的单字符串
  • 必须是合法的标识符。不能是关键字如class,def

rename

  • 注意的参数中使用了*,其后的所有参数必须指定关键字
  • 参数为布尔值
  • 默认为False。当我们指定为True时,如果定义**field_names**参数时,出现非法参数时,会将其替换为位置名称。如['abc', 'def', 'ghi', 'abc']会被替换为['abc', '_1', 'ghi', '_3']

defaults

  • 参数为None或者可迭代对象
  • 当此参数为None时,创建具名元组的实例时,必须要根据field_names传递指定数量的参数
  • 当设置defaults时,我们就为具名元组的元素赋予了默认值,被赋予默认值的元素在实例化的时候可以不传入
  • defaults传入的序列长度和field_names不一致时,函数默认会右侧优先
  • 如果field_names['x', 'y', 'z']defaults(1, 2),那么x是实例化必填参数,y默认为1z默认为2

基本使用

理解了namedtuple函数的参数,我们就可以创建具名元组了

>>> Point = namedtuple('Point', ['x', 'y'])  # 返回一个名为`Point`的类,并赋值给名为`Point`的变量
>>> p = Point(11, y=22)     # 可以根据参数的位置,或具名参数来实例化(像普通的类一样)
>>> p[0] + p[1]             # 具名元组可以像普通元组一样通过`index`访问
33
>>> x, y = p                # 具名元组可以像普通元组一样解包
>>> x, y
(11, 22)
>>> p.x + p.y               # 具名元组还可以通过属性名称访问元组内容
33
>>> p                       # 具名元组在调用`__repr__`,打印实例时,更具可读性
Point(x=11, y=22)
复制代码

具名元组在存储csv或者sqlite3返回数据的时候特别有用

EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')import csv
for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):print(emp.name, emp.title)import sqlite3
conn = sqlite3.connect('/companydata')
cursor = conn.cursor()
cursor.execute('SELECT name, age, title, department, paygrade FROM employees')
for emp in map(EmployeeRecord._make, cursor.fetchall()):print(emp.name, emp.title)
复制代码

特性

具名元组除了拥有继承自基本元组的所有方法之外,还提供了额外的三个方法和两个属性,为了防止命名冲突,这些方法都会以下划线开头

_make(iterable) 这是一个类函数,参数是一个迭代器,可以使用这个函数来构建具名元组实例

>>> t = [11, 22]
>>> Point._make(t)
Point(x=11, y=22)
复制代码

_asdict() 实例方法,根据具名元组的名称和其元素值,构建一个OrderedDict返回

>>> p = Point(x=11, y=22)
>>> p._asdict()
OrderedDict([('x', 11), ('y', 22)])
复制代码

_replace(**kwargs) 实例方法,根据传入的关键词参数,替换具名元组的相关参数,然后返回一个新的具名元组

>>> p = Point(x=11, y=22)
>>> p._replace(x=33)
Point(x=33, y=22)>>> for partnum, record in inventory.items():
...     inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())
复制代码

_fields 这是一个实例属性,存储了此具名元组的元素名称元组,在根据已经存在的具名元组创建新的具名元组的时候使用

>>> p._fields            # view the field names
('x', 'y')>>> Color = namedtuple('Color', 'red green blue')
>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)
>>> Pixel(11, 22, 128, 255, 0)
Pixel(x=11, y=22, red=128, green=255, blue=0)
复制代码

_fields_defaults 查看具名元组类的默认值

>>> Account = namedtuple('Account', ['type', 'balance'], defaults=[0])
>>> Account._fields_defaults
{'balance': 0}
>>> Account('premium')
Account(type='premium', balance=0)
复制代码

使用技巧

  1. 使用getattr获取具名元组元素值
>>> getattr(p, 'x')
11
复制代码
  1. 将字典转换为具名元组
>>> d = {'x': 11, 'y': 22}
>>> Point(**d)
Point(x=11, y=22)
复制代码
  1. 既然具名元组是一个类,我们当然可以随心所欲的进行定制
>>> class Point(namedtuple('Point', ['x', 'y'])):
...     __slots__ = ()
...     @property
...     def hypot(self):
...         return (self.x ** 2 + self.y ** 2) ** 0.5
...     def __str__(self):
...         return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)>>> for p in Point(3, 4), Point(14, 5/7):
...     print(p)
Point: x= 3.000  y= 4.000  hypot= 5.000
Point: x=14.000  y= 0.714  hypot=14.018
复制代码

__slots__值的设置可以保证具名元组保持最小的内存占用

namedtuple纸牌

import collections
# 将纸牌定义为具名元组,每个纸牌都有等级和花色
Card = collections.namedtuple('Card', 'rank suit')class FrenchDeck:# 等级2-Aranks = [str(n) for n in range(2,11)] + list('JQKA')# 花色红黑方草suits = 'spades diamonds clubs hearts'.split()# 构建纸牌def __init__(self):self._cards = [Card(rank, suit) for suit in self.suits for rank in self.ranks]# 获取纸牌def __getitem__(self, position):return self._cards[position]>>> french_deck = FrenchDeck()
>>> french_deck[0]
Card(rank='2', suit='spades')
>>> french_deck[0].rank
'2'
>>> french_deck[0].suit
'spades'
复制代码

轻松掌握namedtuple相关推荐

  1. 为什么要使用namedtuple?

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

  2. 还在为软件测试面试担心?教你一分钟拿捏面试官,轻松拿offer

    1.你做了几年的测试.自动化测试,说一下 selenium 的原理是什么? 我做了五年的测试,1年的自动化测试: selenium 它是用 http 协议来连接 webdriver ,客户端可以使用 ...

  3. centos使用镜像源轻松配置golang+vscode的方法

    Title:centos使用镜像源轻松配置golang+vscode的方法 (阅读时间:约5分钟) 零.序言 最近笔者在上一门名为服务计算的课程,在老师的作业博客中提到,安装golang+vscode ...

  4. 狂神Spring Boot 员工管理系统 超详细完整实现教程(小白轻松上手~)

    [SpringBoot-web系列]前文: SpringBoot-web开发(一): 静态资源的导入(源码分析) SpringBoot-web开发(二): 页面和图标定制(源码分析) SpringBo ...

  5. Python collections 模块 namedtuple、Counter、defaultdict

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

  6. java redis管理_优雅时间管理Java轻松做到,想学么?

    原标题:优雅时间管理Java轻松做到,想学么? 来源 |http://rrd.me/gCQHp 前言:需求是这样的,在与第三方对接过程中,对方提供了token进行时效性验证,过一段时间token就会失 ...

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

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

  8. 技嘉主板bios设置键盘不能用_BIOS不再硬梆梆、全新技嘉主板BIOS设置就算不是玩家也能轻松搞定...

    最近因应AMD推出全新的X570系列主板,小杨也测试了多款各家的主板,可说是把大家都搞得手忙脚乱啊!由于每家厂商的主板都各有特色,为了让玩家们能够了解每款主板的特色和其性能表现,无不卯足全力拼文!不过 ...

  9. 使用Blender Houdini轻松学习FX特效

    大小:1G 含课程文件 时长1h 1280X720 MP4 语言:英语+中英文字幕(根据原英文字幕机译更准确) 使用Blender & Houdini学习轻松的FX 信息: 使用Houdini ...

  10. div模拟textarea文本域轻松实现高度自适应——张鑫旭

    by zhangxinxu from http://www.zhangxinxu.com 本文地址: http://www.zhangxinxu.com/wordpress/?p=1362 一.关于t ...

最新文章

  1. 中小企业对于云计算的3大误解
  2. 展望 | 基于数字化技术的软件生态未来全解析
  3. 2018全球最强物联网公司榜单揭晓|20家企业物联网战略大起底!
  4. 说说设计模式~建造者模式(Builder)
  5. flask mysql项目模板渲染_[Flask] Flask问题集(后端模板渲染项目)
  6. 腾讯这家公司的核心竞争力是什么?为什么?
  7. telegram电脑一直显示连接中_小事不求人!学会这个方法,一个电脑连接多个显示器不再是问题...
  8. 高级指引——自定义节点
  9. codevs 1028 花店橱窗布置 (KM)
  10. vc++中画线时xor_C ++'xor_eq'关键字和示例
  11. IntelliJ Idea学习笔记007---IntelliJ Idea2018 1.6破解
  12. 《Java安全编码标准》一2.11 IDS10-J不要拆分两种数据结构中的字符串
  13. iOS 面试题整理(带答案)二
  14. uniapp 解决切换横竖屏后内容错乱的问题
  15. ASP.NET Core 和 EF Core 系列教程——排序、筛选、分页和分组
  16. ORA-22835:缓冲区对于CLOB到CHAR转换或BLOB到RAWZ转换而言太小
  17. C#毕业设计——基于C#+asp.net+sqlserver的证券术语解释及翻译系统设计与实现(毕业论文+程序源码)——翻译系统
  18. 论文翻译-基于深度残差收缩网络的故障诊断 Deep Residual Shrinkage Networks for Fault Diagnosis
  19. 协议篇————7、HTTP协议详解
  20. [OpenCV实战]29 使用OpenCV实现红眼自动去除

热门文章

  1. 【性能测试】:操作NMON的shell脚本
  2. 日历获取当前月份的月数与当前月份第一天离第一个格子的位置。
  3. 18._6索引器在接口中的使用
  4. 深入剖析ConcurrentHashMap(2)
  5. ZOJ-2364 Data Transmission 分层图阻塞流 Dinic+贪心预流
  6. Baidu All Reduce
  7. POJ 3678 2-SAT简单题
  8. 蛋白序列GO号注释及问题
  9. java解决中文乱码的几种写法
  10. ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库...