推导式表达式是一种可从一个序列构建另外一个新数据序列的数据处理方式,Python中有三种推导式:列表推导式、字典推导式和集合推导式。
列表推导式用于快速生成一个列表:
[表达式 for 变量 in 可迭代对象]
[表达式 for 变量 in 可迭代对象 if 条件]
如生成100内偶数列表:
numbers = [i for i in range(100) if i%2==0]
字典推导式用于快速生成一个字典:
{键:值表达式 for 变量 in 可迭代对象}
{键:值表达式 for 变量 in 可迭代对象 if 条件}
如快速对换字典的键与值:
numMap = {1:'one', 2:'two', 3:'three'}
numRev = {v:k for k,v in numMap.items()}
集合推导式与列表推导式类似,只是外面使用大括号:
{表达式 for 变量 in 可迭代对象}
{表达式 for 变量 in 可迭代对象 if 条件}
如获取字符串中字符数:
s = 'abcdeffsdfsaf'
ch = {x for x in s}
print(len(ch))
一边循环一边计算的机制,称为生成器(generator):
__next__
方法:
StopIteration
异常;for x in g
循环来依次获取生成器中元素;.send()
与next()
类似,但会传递一个值,此值作为yield表达式整体结果返回。生成器与推导式类似,但生成器表达式占更少的内存,因为:
(表达式 for 变量 in 可迭代对象)
(表达式 for 变量 in 可迭代对象 if 条件)
也可把生成器转换为其他集合(tuple或list)来获取其全部元素:
gen = (x**2 for x in range(5))
print(tuple(gen))
通过yield可把普通函数变成生成器:
def genNum(count=10):
for n in range(count):
yield n
num = genNum(5)
for i in num:
print(i)
要使send生效(send的参数为yield的返回值),需要修改yield语句:
def genNum(count=10):
i = 0
while i < count:
v = (yield i)
if v:
i = v
else:
i += 1
num = genNum()
print(next(num)) # 0
print(num.send(3)) # 跳过1、2,返回3
for i in num: # 从4开始
print(i)
能够逐一迭代返回元素的对象即为可迭代对象,包括:
__iter__()
方法的任意对象;__getitem__()
方法的任意对象;定义了__iter__()
(必须返回一个迭代器)方法的对象,就实现了迭代协议;即为一个迭代器:
iter()
方法转换为迭代器:如iter('abcd')
;next()
进行迭代操作;*class GenNumbers:
def __init__(self, count):
self.count = count
def __iter__(self):
self.n = 1
return self
def __next__(self):
if self.n <= self.count:
x = self.n
self.n += 1
return x
else:
raise StopIteration
gen = GenNumbers(10)
for i in gen:
print(i)