记录博客 ZH-BLOG

Python 具名元组与元组拆包

时间:2018-07-30 11:13:10分类:python

元组拆包

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

>>> _, file = os.path.split(r'e:\path\6.jpg') # 用_表示你并不关心的数据
>>> file
'6.jpg'
>> > lax_coordinates = (33.9425, -118.408056)
>> > city, year, pop, chg, area = ('Toko', 2003, 32450, 0.66, 8041)
>> > city
'Toko'
>> > traveler_ids = [('USA', '31195855'), ('BRA', 'CE342567'), ('ESP', 'XDA205856')]
>> > for passport in sorted(traveler_ids):
    print('%s/%s' % passport)

BRA / CE342567
ESP / XDA205856
USA / 31195855
>> > for country, _ in traveler_ids:
    print(country)

USA
BRA
ESP

# 不使用中间变量交换两个变量的值
>> > a = 1
>> > b = 2
>> > b, a = a, b
>> > a
2
>> > b
1
>> > a = 'aaa'
>> > b = 'bbb'
>> > a, b = b, a
>> > a
'bbb'
>> > b
'aaa'

# 使用 * 号解包元组
>> > divmod(20, 8)    # 返回商和余数
(2, 4)
>> > t = (20, 8)
>> > divmod(*t)   # t 被解包
(2, 4)
>> > quotient, remainder = divmod(*t)
>> > quotient
2
>> > remainder
4

# 使用 * 号表示多余的参数
>> > range(5)
range(0, 5)
>> > 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, body, c, d = range(5)
>> > head, body, c, d
([0, 1], 2, 3, 4)
>> > a, b, c = (1, 2, (3, 4))
>> > a, b, c
(1, 2, (3, 4))
>> > a, b, (c, d) = (1, 2, (3, 4))
>> > a, b, c, d
(1, 2, 3, 4)
>> > a, b, c = [1, 2, 3]
>> > a, b, c
(1, 2, 3)

练习:

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('city','lat.','long.'))    # s 默认左对齐
fmt='{:15} | {:9.4f} | {:9.4f}' # d 默认右对齐
for name,cc,pop,(latitude,longitude) in metro_areas:    # 嵌套拆包
    if longitude<0:
        print(fmt.format(name,latitude,longitude))

具名元组

collections.namedtuple 是一个工厂函数, 它可以用来构建一个带字段名的元组和一个有名字的类。具名元组比普通实体对象要小,因为 Python 不会用 __dict__ 来存放这些实例的属性。

>>> 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.population
36.933
>>> tokyo.coordinates
(35.689722, 139.691667)
>>> tokyo[1]
'JP'

具名元组类属性和方法:

fields 类属性、 类方法 _make(iterable) 和实例方法 _asdict()。

>>> City._fields
('name', 'country', 'population', 'coordinates')
>>> LatLong = namedtuple('LatLong', 'lat long')
>>> delhi_data = ('Delho NCR', 'IN', 21.935, LatLong(28.613889, 77.208889))
>>> delhi = City._make(delhi_data)
>>> delhi
City(name='Delho NCR', country='IN', population=21.935, coordinates=LatLong(lat=28.613889, long=77.208889))
>>> dic = delhi._asdict()
>>> dic
OrderedDict([('name', 'Delho NCR'), ('country', 'IN'), ('population', 21.935), ('coordinates', LatLong(lat=28.613889, long=77.208889))])
>>> dic['abc'] = 'abc' # 具名元组是不可变大,字典是可变得
>>> dic
OrderedDict([('name', 'Delho NCR'), ('country', 'IN'), ('population', 21.935), ('coordinates', LatLong(lat=28.613889, long=77.208889)), ('abc', 'abc')])
>>> for key, value in dic.items():
	print(key, value)

	
name Delho NCR
country IN
population 21.935
coordinates LatLong(lat=28.613889, long=77.208889)
abc abc