第2章:序列构成的数组-元组、元组拆包、具名元组

3.1 元组拆包 

    拆包可以应用到任何可迭代对象上(strlist等),唯一的硬性要求是,被可迭代对象中的元素数量必须要跟接受这些元素的元组的空档数一致。除非我们用 * 来表示忽略多余的元素

平行赋值拆包:
完全拆包,左侧变量必须和元组元素数量一致;

# 平行赋值
city, year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8014)
print(city, year, pop, chg, area)  # Tokyo 2003 32450 0.66 8014

_ 占位不需要的元素: 

# 用 _ 占位不需要的元素
city, _, _ = ('Tokyo', 2003, 32450)
print(city)  # Tokyo

 *vars 处理多余的元素: 

# 用 * 处理多余的元素
city, year, *other = ('Tokyo', 2003, 32450, 0.66, 8014)
print(city, year, other)  # Tokyo 2003 [32450, 0.66, 8014]

* 拆包元组作为函数的参数: 

# 用 * 拆包元组作为函数的参数
t = (3, 4)
dt = divmod(*t)  # divmod() 计算两个数值,返回商和余数
print(dt)  # (0, 3)

3.2 嵌套元组拆包 

 接受表达式的元组可以是嵌套式的,例如 (a, b, (c, d))。只要这个接受元组的嵌套结构符合表达式本身的嵌套结构,Python 就可以作出正确的对应。


# 嵌套元组拆包
metro_areas = [
    ('Tokyo', 'JP', 36, (35, 139)),
    ('Delhi NCR', 'IN', 21, (28, 77)),
    ('Sao Paulo', 'BR', 19, (-23, -46)),
]

# metro_areas 的元素是嵌套元组
for city, country, pop, (lat, long) in metro_areas:
    print(city, country, pop, lat, long)  

# Tokyo JP 36 35 139
# Delhi NCR IN 21 28 77
# Sao Paulo BR 19 -23 -46

 3.3 具名元组

collections.namedtuple 是一个工厂函数,它可以用来构建一个带字段名的元组和一个有名字的类——这个带名字的类对调试程序有很大帮助。 

import collections

# 创建一个具名元组需要两个参数,一个是类名,另一个是类的各个字段的名字。
# 后者可以是由数个字符串组成的可迭代对象,或者是由空格分隔开的字段名组成的字符串。
Point = collections.namedtuple('Points', ['x', 'y'])
print(Point.__doc__, type(Point))  # Points(x, y) <class 'type'>

# 返回字段名
print(Point._fields)  #   # ('x', 'y')

# 接受一个可迭代对象作为字段,创建一个新的类实例
c = (1, 2)
j = Point._make(c)

# 用位置参数或关键字实例化
p = Point(11, y=22)
a = p[0] + p[1]  # 可以像普通元组一样索引取值
print(a)  # 33

# 可以像普通元组一样拆包
x, y = p
print(x, y)  # 11 22
# 可以像对象一样访问属性
print(p.x, p.y)  # 11 22

# 可以转成字典格式(collections.OrderedDict 类型,不是真正的字典)
d = p._asdict()
print(d['x'], d.get('x'))  # 11

# 字典拆包传值
Point(**d)  # Point(x=11, y=22)

# 替换目标的值
p._replace(x=100)  # _replace() is like str.replace() but targets named fields
# Point(x=100, y=22)

3.3 作为不可变列表的元组

如果要把元组当作列表来用的话,最好先了解一下它们的相似度如何。在表 2-1 中可以清楚地看到,除了跟增减元素相关的方法之外,元组支持列表的其他所有方法。还有一个例外,元组没有 __reversed__ 方法,但是这个方法只是个优化而已,reversed(my_tuple) 这个用法在没有 __reversed__ 的情况下也是合法的。

表2-1:列表或元组的方法和属性(那些由object类支持的方法没有列出来)

 

列表

元组

 

s.__add__(s2)

s + s2,拼接

s.__iadd__(s2)

 

s += s2,就地拼接

s.append(e)

 

在尾部添加一个新元素

s.clear()

 

删除所有元素

s.__contains__(e)

s 是否包含 e

s.copy()

 

列表的浅复制

s.count(e)

e 在 s 中出现的次数

s.__delitem__(p)

 

把位于 p 的元素删除

s.extend(it)

 

把可迭代对象 it 追加给 s

s.__getitem__(p)

s[p],获取位置 p 的元素

s.__getnewargs__()

 

在 pickle 中支持更加优化的序列化

s.index(e)

在 s 中找到元素 e 第一次出现的位置

s.insert(p, e)

 

在位置 p 之前插入元素e

s.__iter__()

获取 s 的迭代器

s.__len__()

len(s),元素的数量

s.__mul__(n)

s * nn 个 s 的重复拼接

s.__imul__(n)

 

s *= n,就地重复拼接

s.__rmul__(n)

n * s,反向拼接 *

s.pop([p])

 

删除最后或者是(可选的)位于 p 的元素,并返回它的值

s.remove(e)

 

删除 s 中的第一次出现的 e

s.reverse()

 

就地把 s 的元素倒序排列

s.__reversed__()

 

返回 s 的倒序迭代器

s.__setitem__(p, e)

 

s[p] = e,把元素 e 放在位置p,替代已经在那个位置的元素

s.sort([key], [reverse])

 

就地对 s 中的元素进行排序,可选的参数有键(key)和是否倒序(reverse

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值