8.3-元组和命名元组

元组

Tuple  Docstring:     
tuple() -> empty tuple  ;
tuple(iterable) -> tuple initialized from iterable's items
1. 元组的优点 (相比于列表)

1.通常将元组用于不同的数据类型,将列表用于相同(或相似)的数据类型。
2.由于元组不可变,所以对元组的迭代比列表要快(性能略有提升)。
3.元组可以用作字典的 key,而列表不行(因为字典的 key 必须是不可变的,而元组本身就是不可变的)。
4.如果数据不需要更改,将其作为元组来实现可以确保“写保护”。

2. 元组的定义
Python 中,元组由内置的 tuple 类型定义。
创建元组,需要将所有元素放在圆括号(())内,以逗号(,)分隔;

构造只有一个元素的元组比较特殊,括号内只包含一个元素是不够的,还需要在元素后添加一个逗号;

t=(1)    # 改变优先级 int/str/float ;  
t=(1,)  # 元祖类型;

元组中的元素可以有任意多个,并且可以是不同类型的(例如:数字、字符串、列表等):

>>> t = ()                        # 空元组
>>>
>>> t = ('P', 'y')                # 字符串类型元组
>>>
>>> t = (1, 5.5, 'Python')        # 混合类型元组
>>>
>>> t = (6, 'Hello', ('P', 'y'))  # 嵌套元组
>>>
>>> t = 1, 5.5, 'Python'          # 元组可以没有括号,称为元组包装
>>> t
(1, 5.5, 'Python')
>>>
>>> a, b, c = t                   # 元组解包
>>> a
1
>>> b
5.5
>>> c
'Python'

加法和乘法仍然是可以;
t2 =(2,)
t2+t2      |    (2, 2)

t2*3    |    (2, 2, 2)

3.更改元组
元组是不可变的,也就是说,元组中的元素在被赋值后不能改变。

但是,如果元素本身是一个可变数据类型(例如:列表、字典),那么其嵌套项可以被改变:

>>> t = (6, 'Hello', ['P', 'y'])
>>>
>>> t[0] = 10      # 不能改变元素
...
TypeError: 'tuple' object does not support item assignment
>>>
>>> t[2][1] = 's'  # 可变元素内部可以被改变
>>> t
(6, 'Hello', ['P', 's'])

4.删除元组
如上所述,不能更改元组中的元素,这也意味着无法删除元组中的元素。
但如果元素本身是一个可变数据类型,那么其嵌套项是可以被删除的,而且使用关键字 del 可以删除整个元组:


>>> t = (6, 'Hello', {'name':'Waleon', 'age':18})
>>>
>>> del t[2]          # 不能删除元素
...
TypeError: 'tuple' object doesn't support item deletion
>>>
>>> del t[2]['name']  # 可变元素的嵌套项可以被删除 
>>> t
(6, 'Hello', {'age': 18})
>>>
>>> del t             # 可以删除整个元组
>>> t
...
NameError: name 't' is not defined
2.1 元组方法

元组中的方法相对较少,可以通过 dir() 来查看方法列表:

>>> dir(tuple)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
 '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__',
 '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', 
'__subclasshook__', 'count', 'index']

可以看到,有可用的方法:

元组方法:

方法 描述
index() 返回第一个匹配的索引
count() 统计某个元素在列表中出现的次数
len(tuple) 返回元素的个数

元组:count/index方法都是O(n) ; 随着规模的增大,而效率下降;

2.2 列表和元组互转

列表和元组之间可以相互转换,分别使用 tuple() 和 list() 来实现

>>> l = ['H', 'e', 'l', 'l', 'o']
>>> tx = tuple(l)  # 列表转元组
>>> tx
('H', 'e', 'l', 'l', 'o')
>>>
>>> t = ('P', 'y')
>>> lx = list(t)   # 元组转列表
>>> lx
['P', 'y']

既然可以互转,那么要改变元组,可以先将其转化为列表,对列表进行更改,然后再将列表转换为元组。
例如,删除元组中的元素:

>>> t = ('P', 'y')
>>>
>>> lx = list(t)    # 将元组转换为列表
>>> lx.remove('y')  # 删除列表中的元素
>>> t = tuple(lx)   # 再将列表转换为元组
>>> t
('P',)

注意:元组本身是不可变的,这里说的并不是传统意义的改变(增、删、改),相当于元组的重新赋值。

元组还有些什么?

元组也支持一些基本操作,例如:连接(+)、重复(*)、成员测试(in/not in)等。此外,它还可以与一些内置函数一起使用来执行不同的任务,例如:min()、max()、len() 等。这里就不再介绍了,请参考 Python 列表

高级元组namedtuple

1.顾名思义,就是带有名字的元组,这是什么意思呢?就是取值时不再需要通过下标索引的方式来获取了,可以直接叫名字(字段名),先来看怎么定义的吧。

命名元组,返回一个元组的子类,并定义了字段;
field_names可以是空白符或逗号分隔的字段的字符串,可以是字段的列表

from collections import namedtuple
# 定义namedtuple类
User = namedtuple("User", 'name gender height weight')

# 或者
# User = namedtuple("User", ['name', 'gender', 'height', 'weight'])

# 初始化namedtuple实例对象
user = User(name="jack", gender="female", height=170, weight=120)

user.name    #'jack'
user.gender   #'female'

模块导入的两种方式:
import collections
from collections import namedtuple

定义 namedtuple 时,第一个参数就是元组的名字,这里很像我们自定义类中的类名,第二个参数是用空格隔开的字符串(也可以是字符串组成的列表),代表元组中的4个字段,相当于类中的4个属性。初始化方式和类的实例对象是一样的,如果用普通类来定义可表示为:

class User:
    def __init__(self, name, gender, height, weight):
        self.name = name
        self.gender = gender
        self.height = height
        self.weight = weight
user = User(name="jack", gender="female", height=170, weight=120)
user.name  #'jack'

对比起来,其实 namedtuple 就是一个轻量级的类,代码更简洁,当我们的类非常简单,只有属性又不需要定义其他方法时,完全可以用 namedtuple 来代替类,使用 namedtuple 效率比使用普通类更高效,同样因为内部不需要维护太多的东西。

2. namedtuple其实是继承 tuple 的一个子类,它保留了 tuple 的特性,比如通过索引获取元素,切片功能,同样地,字段不能重新赋值。

>>> user[1:3]
('female', 170)

>>> user[0]
'jack'

>>> user.name = 'bob'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

namedtuple 比 tuple 的优势在于 namedtuple 具有可自我描述的特点,因为 tuple 中的值不看上下文你不知道具体代表什么,而 namedtuple 自己就可以说明各字段代表什么。

源码的阅读

帮助文档看不懂,看源码;源码中很多地方用到了namedtuple
map(str,a)生成可迭代对象;一一转换;

ASCLL码与拓展ASCLL码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352