Python学习笔记(四)—— Tuple

来源:互联网 发布:香蕉网络tv免费频道 编辑:程序博客网 时间:2024/06/08 08:13

代码及内容源自《Fluent Python》——Luciano Ramalho 著

Tuples
Tuple可以被用作列表,也可以被用作没有字段名的记录。对于后者来说,每条记录所包含的项数以及项的顺序则至关重要。

>>> lax_coordinates=(33.9425,-118.408056) # latitude and longitude of LA international airport>>> city,year,pop,chg,area=('Tokyo',2003,32450,0.66,8014) # Data about Tokyo>>> traveler_ids=[('USA','31195855'),('BRA','CE342567'),('ESP','XDA205856')] # A list of tuples (country_code, passport_number)>>> for passport in sorted(traveler_ids):...    print('%s/%s' % passport)
BRA/CE342567ESP/XDA205856USA/31195855
>>> for country,_ in traveler_ids:...    print(country)
USABRAESP

Tuple unpacking
最显而易见的拆封方式是并行赋值。

>>> latitude, longitude=lax_coordinates # tuple unpacking>>> latitude
33.9425
>>> longitude
-118.408056

另一个方式是当调用函数时,在tuple变量前加*号。

>>> divmod(20,8)
(2, 4)
>>> t=(20,8)>>> divmod(t)
---------------------------------------------------------------------------TypeError                                 Traceback (most recent call last)<ipython-input-18-2cd06b5f0069> in <module>()      1 t=(20,8)----> 2 divmod(t)TypeError: divmod expected 2 arguments, got 1
>>> divmod(*t)
(2, 4)

有时我们只关心tuple中的某些部分,这时可以利用下划线_来做占位符。

>>> import os>>> _, filename=os.path.split('/home/luciano/.ssh/idrsa.pub') # os.path.split() builds a tuple(path, last_part)>>> filename
'idrsa.pub'

此外,变量前加*的拆封方式可以扩展到并行赋值中

>>> a,b,*rest=range(5)>>> a, b, rest
(0, 1, [2, 3, 4])
>>> a,b,*rest=range(3)>>> a, b, rest
(0, 1, [2])
>>> a,b,*rest=range(2)>>> a, b, rest
(0, 1, [])

在上述情况下,*只能作用于其中的一个变量,但是位置可以任意。

>>> a, *body,c,d=range(5)>>> a,body,c,d
(0, [1, 2], 3, 4)
>>> *head,b,c,d=range(5)>>> head,b,c,d
([0, 1], 2, 3, 4)

嵌套Tuple的拆封,所用表达式一定要和嵌套格式相匹配。

>>> 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)),]>>> print('{:15} | {:^9} | {:^9}'.format('','lat.','long.'))>>> fmt = '{:15} | {:9.4f} | {:9.4f}'>>> for name, cc, pop, (latitude,longitude) in metro_areas:    if longitude <= 0:        print(fmt.format(name,latitude,longitude))
                |   lat.    |   long.  Mexico City     |   19.4333 |  -99.1333New York-Newark |   40.8086 |  -74.0204Sao Paulo       |  -23.5478 |  -46.6358

Named Tuples
Tuple本身已经被设计的非常方便,但是作为记录使用时,我们偶尔会希望能够给字段命名。这正是namedtuple但是的初衷。

>>> from collections import namedtuple>>> City = namedtuple('City', 'name country population coordinates')>>> tokyo = City('Tokyo','JP',36.933,(35.689722,139.691667))>>> tokyo
City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139.691667))
>>> tokyo.population
36.933
>>> tokyo.coordinates
(35.689722, 139.691667)

namedtuple中最常用的几个属性_fileds,_make(iterable),_asdict()

>>> City._fields # 返回字段名的tuple
('name', 'country', 'population', 'coordinates')
>>> Latlong=namedtuple('Latlong','lat long')>>> delhi_data=('Delhi NCR','IN',21.935,Latlong(28.613889,77.208889))>>> delhi=City._make(delhi_data) #利用iterable来实例化一个namedtuple,效果同City(*delhi_data)>>> delhi._asdict() #将namedtuple转换成dict
OrderedDict([('name', 'Delhi NCR'),             ('country', 'IN'),             ('population', 21.935),             ('coordinates', Latlong(lat=28.613889, long=77.208889))])
>>> for key, value in delhi._asdict().items():...    print(key+':',value)
name: Delhi NCRcountry: INpopulation: 21.935coordinates: Latlong(lat=28.613889, long=77.208889)