参考链接: Python | 生成器表达式
解析式和生成器表达式
列表解析List Comprehension
语法
[返回值 for 元素 in 可迭代对象 if 条件]使用中括号[],内部是for循环,if条件语句可选,会返回一个新的列表 列表解析试优点
编译器会优化,不会因为简写而影响效率,反而因优化提高了效率减少程序工作量,减少出错简化代码,可读性增强 简单示例:
例子No1
#NO1 返回1-10平方的列表
[_*_ for _ in range(1,11)]
例子No2
#NO2 有一个列表lst = [1,4,9,16,2,5,10,15],生成一个新列表,要求新列表元素是lst相邻2项的和
lst = [1,4,9,16,2,5,10,15]
[lst[i]+lst[i+1] for i in range(len(lst)-1)]
例子No3
#No3 打印9*9乘法表
var = [print("{}*{}={}".format(j,i,i*j),end="\n" if i==j else "\t") for i in range(1,10) for j in range(1,i+1)]
例子No4
#No4 "0001.abadicddws"是ID格式,要求ID格式是以点分割,左边4位从1开始的整数,右边是10位随机小写英文字母,请依次生成100个ID的列表
import random,string
#["{:0>4}.{}{}{}{}{}{}{}{}{}{}".format(i,*[random.choice(string.ascii_lowercase) for _ in range(10)]) for i in range(1,101)]
#["{:0>4}.{}".format(i,bytes(random.choices(range(97,123),k=10)).decode()) for i in range(1,101)]
["{:0>4}.{}".format(i,"".join(random.choices(string.ascii_lowercase,k=10))) for i in range(1,101)]
生成器表达式Generator expression
语法
(返回值 for 元素 in 可迭代对象 if 条件)使用小括号(),内部是for循环,if条件语句可选,会返回一个生成器对象 生成器与列表解释器的区别
生成器表达式是按需计算(或称为惰性求值、延迟计算),需要的时候才计算值列表解析式是立即返回值 生成器:是一个可迭代对象。是一个迭代器 例子:
生成器表达式 g = ( _ for _ in range(10))
print(g)
key = next(g) #生成器g游标下移一位。并返回第一个值
for x in g: # 由于生成器是按需计算,只有当需要对x进行赋值时,才会从生成器g中计算出当前游标对应的值。赋给x
print(x)
print("-----------------")
for x in g: #注意:生成器游标不能回滚,即后退。生成器只能迭代一次。所以本次迭代没有数据
print(x)
2. 例子3:生成器中的闭包 def getcont():
key = 5
hh = (key+i for i in range(4))
key = 100 #注意此时生成器中的key对应的值会变成100
return hh
hh = getcont() ## 注意此时生成器中key对应的值变成100,形成闭包。
key = 120 #此时key与hh中生成器的key不同
list(hh)
生成器表达式和列表解析式的区别
计算方式
生成器表达式:延迟计算,按需取值。列表解析器:立即计算,得到所有值 内存占用
生成器表达式:节约内存,生成器对象是个对象,需要数据时就计算获取一个值列表解析式:占用内存与数据总量一致。 计算速度:两者设计思路不一致,没有可比性。
集合解析式
语法
{返回值 for 元素 in 可迭代对象 if 条件}使用大括号{},值必须是可哈希,内部是for循环,if条件语句可选,会返回一个集合 用法
{(x,x+1) for x in range(10)}
{ _ for _ in range(10)}
字典解析式
语法
{返回值 for 元素 in 可迭代对象 if 条件}使用大括号{},值使用key:value形式定义,key必须是可哈希,内部是for循环,if条件语句可选,会返回一个字典 用法
dictt1 = { x:x+1 for x in range(10)}
dictt2 = {x:[x+1] for x in range(10)}
dictt3 = {(x,):[x+1] for x in range(10)}
dictt4 = {str(x):[x,x+1] for x in range(10)}
dictt5 = {chr(0x41+x):x**2 for x in range(10)}
print(dictt1,dictt2,dictt3,dictt4,dictt5,sep="\n")
总结
Python2 引入列表解析式Python2.4 引入生成器表达式Python3 引入集合、字典解析式,并迁移到了2.7
一般来说应该多用解析式,简短、高效。如果一个解析式非常复杂难读懂,要考虑使用for循环生成器和迭代器是不同的对象,单都是可迭代对象
生成器对象—》一定是迭代器—》一定可迭代迭代器:能用next()函数调用取下一个值。是迭代器 —》一定可迭代可迭代对象,不一定是迭代器,也不一定是生成器对象