In [6]:
symbols = "a%b&c$de$"
beyond_ascii = [ord(s) for s in symbols if ord(s) > 50]
beyond_ascii
Out[6]:
In [8]:
beyond_ascii = list(filter(lambda c: c > 50, map(ord, symbols)))
beyond_ascii
Out[8]:
对于上面的例子来说, filter/map 并不比 listcomp(列表生成式) 快, 后面的章节我们进一步讨论
In [10]:
colors = ['black', 'white']
sizes = ['S', 'M', 'L']
tshirts = [(color, size) for color in colors #两种颜色,三种尺寸的方式创建列表
for size in sizes]
tshirts
Out[10]:
Python中,[], {}, () 内的换行符会被忽略,所以我们在创建列表,字典等时,不必使用 \
来换行,列表推导式的作用只有一个,生成列表,如果想生成其它类型的序列,生成器就派上了用场。
In [3]:
symbols = "a%b&c$de$"
tuple(ord(s) for s in symbols) #如果生成器是一个函数的唯一的参数,则不用重复使用括号
Out[3]:
In [5]:
import array
array.array('I', (ord(symbol) for symbol in symbols)) #不是唯一的参数,所以必须要加上括号
Out[5]:
In [8]:
lax_coordinates = (33.942, -118.4080) #经纬度
city, year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8014) #Tokyo 的资料,包括名称年份人口人口变化和面积
traveler_ids = [('USA', '31195855'), ('BRA', 'CE342567'), ('ESP', 'XDA205856')] #country_code,passport_number
for passport in sorted(traveler_ids):
print('%s/%s' % passport)
In [9]:
for country, _ in traveler_ids:
print(country)
In [10]:
lax_coordinates = (33.348, -117.932)
latitude, longitude = lax_coordinates # tuple 拆解
print(latitude)
print(longitude)
不用中间变量交换值,是元组拆包的另一种应用
In [11]:
a = 3
b = 5
a, b = b, a
a
Out[11]:
另一种元组拆包,调用函数时,参数前面加个星号
In [14]:
divmod(20, 8) #a 除 b,返回商和余数
Out[14]:
In [16]:
t = (20, 8)
divmod(*t)
Out[16]:
In [17]:
quotient, remainder = divmod(*t)
quotient, remainder
Out[17]:
上面也是一种元组拆包方法,调用函数时候用 * 把可迭代对象拆开作为函数参数。
下面的例子是让一个函数可以使用元组的方式返回多个值,os.path.split()
函数返回一个以路径和最后一个文件名组成的元组(path, last_part)
In [18]:
import os
_, filename = os.path.split('/home/kaka/.ssh/idrsa.pub')
filename
Out[18]:
In [19]:
a, b, *rest = range(5)
a, b, rest
Out[19]:
In [20]:
a, b, *rest = range(3)
a, b, rest
Out[20]:
In [21]:
a, b, *rest = range(2)
a, b, rest
Out[21]:
在平行赋值情况下, * 前置符只能用在一个变量前面,但是可以这个变量可以是任意位置
In [23]:
a, *body, c, d = range(5)
a, body, c, d
Out[23]:
In [24]:
*head, b, c, d = range(5)
head, b, c, d
Out[24]:
In [2]:
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.43333, -99.13333)),
('Net York-Newark', 'US', 20.104, (40.808611, -74.020386)),
('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635883))
]
print('{:15} | {:^9} | {:^9}'.format('', 'lat.', 'long.')) #^9 表示占 9 个字符,居中显示
fmt = '{:15} | {:^9} | {:^9}'
for name, cc, pop, (latitude, longitude) in metro_areas:
if longitude <= 0: #西半球
print(fmt.format(name, latitude, longitude))
在 python3 之前,你可以在定义函数时,可以使用嵌套元组做形参,例如 def func(a, (b, c), d)。但是 python3 已经不支持了,不过这对函数调用者没有任何影响,它改变的是某些函数的声明方式
按照设计,tuple 是非常方便的,可以把它当成记录来使用,不过它不可以指定名字,这也是 namedtuple 被设计出来的原因
collections.namedtuple
是一个工厂函数,可以构建一个带字段名的元组和一个有名字的类。这个带名字的类对调试程序有很大的帮助。使用 namedtuple 创建的实例消耗的内存与元组是一样的,因为字段名都被存储到相应的类中。这个实例跟普通的对象实例比起来要小一些,因为 Python 不会用到 __dict__
来存放这些实例的属性
下面展示了如何用具名元组来记录一个城市的信息。
In [27]:
from collections import namedtuple
City = namedtuple('City', 'name country population coordinates')
tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667))
tokyo
Out[27]:
In [28]:
tokyo.coordinates
Out[28]:
In [29]:
tokyo[1]
Out[29]:
构建 namedtuple 需要两个参数,第一个是类名,另一个是各个字段的名字,可以使用可迭代的字符串(列表),也可以使用用空格分隔的字符串。
存放在对应字段里的数据要以一串参数的形式传入到构造函数中。注意,元祖的构造函数值接受单一的可迭代对象。
可以用字段名或位置来读取数据
下面是 namedtuple 的常用属性:
In [31]:
City._fields #是 1 个元组,里面是我们的字段名
Out[31]:
In [33]:
LatLong = namedtuple('LatLong', 'lat long')
delhi_data = ('Delhi NCR', 'IN', 21.935, LatLong(28.613889, 77.208889))
delhi = City._make(delhi_data) #_make() 可以让我们接受一个可迭代对象生成这个类的一个实例。City(*delhi_data) 也可以做这件事
delhi._asdict() #把具名元组按照 collections.OrderedDict 的形式返回, 用来友好的显示城市资料
Out[33]: