博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
说说 Python 元组的高级用法
阅读量:1902 次
发布时间:2019-04-26

本文共 4850 字,大约阅读时间需要 16 分钟。

1 元组记录

元组可以当做存放数据的记录。元组中的元素用于存放记录字段数据,而元素所在的位置用于表达该字段的隐含含义。

Luciano Ramalho 举了这样一个示例:

lax_coordinates=(33.33,-11.92)logging.info('longitude -> %s',lax_coordinates[0])logging.info('latitude -> %s',lax_coordinates[1])city,year,pop,chg,area=('Tokyo',2013,232,0.22,281)logging.info('city -> %s',city)logging.info('area -> %s',area)traveler_ids=[('USA','232'),('ESP','11')]for passport in sorted(traveler_ids):    logging.info('%s/%s' % passport)for country,_ in traveler_ids:    logging.info('country -> %s',country)

运行结果:

INFO - longitude -> 33.33INFO - latitude -> -11.92INFO - city -> TokyoINFO - area -> 281INFO - ESP/11INFO - USA/232INFO - country -> USAINFO - country -> ESP
  1. 可利用元组的位置,得到相关数据,但必须清楚该位置所指向的数据含义。
  2. 也可以利用元组,给多个变量一次性赋值。
  3. 利用 for 循环可以分别提取出元组里的元素,这叫作拆包(unpacking)。
  4. 第三个用例是先排序,然后再拆包到一个变量,最后用 % 格式运算符将自动匹配到对应的元组元素中打印出来。
  5. 第四个用例是先拆包到一个变量和一个占位符 _,然后打印出这个变量。

2 元组拆包

利用元组拆包,我们可以使用一行代码,同时给多个变量一次性初始化赋值。

元组拆包可以应用到任何可迭代对象上。这些可迭代对象中的元素数必须要跟接受这些元素的元组的空档数一致。

(1)数据交换

利用元组拆包,可以很优雅地通过一行代码实现两个变量之间的数据交换。

a = 1b = 2a, b = b, alogging.info('a -> %s',a)logging.info('b -> %s',b)

运行结果:

INFO - a -> 2INFO - b -> 1

(2)拆分函数入参

利用 * 运算符可以把一个可迭代对象拆分成某个函数的多个入参。

r = divmod(20, 8)logging.info('r -> %s', r)i = (20, 8)r = divmod(*i)logging.info('r -> %s', r)quotient, remainder = divmod(*i)logging.info('quotient -> %s', quotient)logging.info('remainder -> %s', remainder)

运行结果:

INFO - r -> (2, 4)INFO - r -> (2, 4)INFO - quotient -> 2INFO - remainder -> 4

python 的 divmod() 函数,会返回一个包含商和余数的元组。divmod(a, b) 中,a 是被除数,b 是除数,而返回的结果是 (商,余数)。

(3)占位符方式

在进行拆包的时候,如果有些返回值不是我们想要的,可以使用 _ 占位符忽略它们。

_,filename=os.path.split('/home/xxx/readme.txt')logging.info('filename -> %s',filename)

运行结果:

INFO - filename -> readme.txt

os.path.split() 函数会返回以路径和最后一个文件名组成的元 组 (path, last_part),而我们只需要文件名,那么这里就可以使用 _ 占位符忽略路径值。

(4)处理多余的值

在多值赋值的场景下,我们可以使用 * 来处理剩下的值。所谓的剩下的值,就是没有明确被赋值的值。

a, b, *rest = range(5)logging.info('a,b,rest -> %s,%s,%s', a, b, rest)a, b, *rest = range(3)logging.info('a,b,rest -> %s,%s,%s', a, b, rest)a, b, *rest = range(2)logging.info('a,b,rest -> %s,%s,%s', a, b, rest)

运行结果:

INFO - a,b,rest -> 0,1,[2, 3, 4]INFO - a,b,rest -> 0,1,[2]INFO - a,b,rest -> 0,1,[]

* 的变量可以是左侧变量表达式中的任意一个变量。

a, *body, c, d = range(5)logging.info('a, body, c, d -> %s,%s,%s,%s', a, body, c, d)*head, b, c, d = range(5)logging.info('head,b,c,d -> %s,%s,%s,%s', head, b, c, d)

运行结果:

INFO - a, body, c, d -> 0,[1, 2],3,4INFO - head,b,c,d -> [0, 1],2,3,4

3 嵌套元组拆包

只要接受元组的嵌套结构与表达式本身的嵌套结构一致, Python 就可以自动拆包。

metro_areas = [('Tokyo', 'JP', 36.933, (35.689722, 139.691667)), ('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)),               ('Mexico City', 'MX', 20.142, (19.433333, -99.133333)),               ('New York-Newark', 'US', 20.104, (40.808611, -74.020386)),               ('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833)),               ]fmt = '{:15} | {:9.4f} | {:9.4f}'for name, cc, pop, (latitude, longitude) in metro_areas:    if longitude <= 0:        logging.info(fmt.format(name, latitude, longitude))

运行结果:

INFO - Mexico City     |   19.4333 |  -99.1333INFO - New York-Newark |   40.8086 |  -74.0204INFO - Sao Paulo       |  -23.5478 |  -46.6358

经纬度是经度与纬度的合称组成一个坐标系统,称为地理坐标系统,它是一种利用三度空间的球面来定义地球上的空间的球面坐标系统,能够标示地球上的任何一个位置。

负纬度表示位于南半球(S)的位置而负经度表示西半球(W)的位置。示例代码中,元组拆包后,过滤出西半球的坐标,然后打印出来。

4 具名元组

4.1 用法

我们可以利用 collections.namedtuple 这个工厂函数来构建一个带名字的元组。

用 namedtuple 构建的类的实例跟普通的对象实例相比,所占用的内存要小一些,因为 Python 没有使用 dict 来存放这些实例的属性。

from collections import namedtupleCity=namedtuple('City','name country population coordinates')tokyo=City('Tokyo', 'JP', 36.933, (35.689722, 139.691667))logging.info('tokyo -> %s',tokyo)logging.info('population -> %s',tokyo.population)logging.info('tokyo[0] -> %s',tokyo[0])logging.info('tokyo[1] -> %s',tokyo[1])

运行结果:

INFO - tokyo -> City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139.691667))INFO - population -> 36.933INFO - tokyo[0] -> TokyoINFO - tokyo[1] -> JP

创建一个具名元组需要两个入参,一个是类名,另一个是类中各个字段的名字。后者是由空格分隔开的字段名所组成的字符串。City=namedtuple('City','name country population coordinates')

放入数据时,需要把数据以逗号分隔的形式传入到具名类的构造函数中。tokyo=City('Tokyo', 'JP', 36.933, (35.689722, 139.691667))

然后就可以通过字段名或者位置来获取具名元组中的某个字段的信息。tokyo.populationtokyo[0]

4.2 专有属性

除了从普通元组那里继承来的属性之外,具名元组还定义了一些自己的专有属性。

  • _fields 属性包含了这个类所有字段名称元组。
  • _make() 方法接受一个可迭代对象来生成这个类的一个实例。
  • _asdict() 方法会把具名元组以 collections.OrderedDict 的形式返 回出来,我们可以利用它来打印出元组中的信息。
logging.info('_fields -> %s',City._fields)LatLong = namedtuple('LatLong', 'lat long')delhi_data = ('Delhi NCR', 'IN', 21.935, LatLong(28.613889, 77.208889))delhi = City._make(delhi_data)logging.info('delhi._asdict() -> %s',delhi._asdict())

运行结果:

INFO - _fields -> ('name', 'country', 'population', 'coordinates')INFO - delhi._asdict() -> OrderedDict([('name', 'Delhi NCR'), ('country', 'IN'), ('population', 21.935), ('coordinates', LatLong(lat=28.613889, long=77.208889))])

示例中的 delhi_data 是一个嵌套结构,内部嵌套了包含经纬度信息的具名元组。

转载地址:http://tfdcf.baihongyu.com/

你可能感兴趣的文章
Oracle的高水位线介绍
查看>>
Oracle 10g DBCA建库四个选项的区别------ 一般用途 事务处理 定制数据库数据仓库
查看>>
ora-01658 :无法为表空间USERS 中的段创建INITIAL区
查看>>
(总结)Linux的chattr与lsattr命令详解
查看>>
chattr和lsattr命令
查看>>
数据块(Data Block)原理深入剖析
查看>>
Oracle体系结构
查看>>
Database、User、Schema、Tables、Col、Row等之间的关系
查看>>
深入剖析oracle备份与恢复原理
查看>>
GIS数据库ORACLE的某些参数设置
查看>>
多元化控制文件和重做日志文件
查看>>
信令网
查看>>
1号信令、7号信令和PRI信令
查看>>
信令点编码
查看>>
E1通信的基础知识
查看>>
中继卡与语音卡
查看>>
普通固定电话机使用与原理简介
查看>>
电脑声卡的工作原理
查看>>
PBX
查看>>
G.703 V.35接口
查看>>