推到表达式与生成器表达式
推导表达式
推导式,一种简写方式,x推导式的结果是推导出的一个x对象
# 列表推导式
a = [string for string in ["AAA", "BBB", "CCC"]]
print(a, type(a)) # ['AAA', 'BBB', 'CCC'] <class 'list'>
# 字典推导式
a = {k: v for k, v in enumerate(["AAA", "BBB", "CCC"])}
print(a, type(a)) # {0: 'AAA', 1: 'BBB', 2: 'CCC'} <class 'dict'>
# 集合推导式
a = {string for string in ["AAA", "BBB", "CCC"]}
print(a, type(a)) # {'AAA', 'BBB', 'CCC'} <class 'set'>
注:
字典推导式遇到重复key取最后一个,与字典添加重复key逻辑一致
print({k: v for k, v in [(1, 1), (2, True), (2, False), (3, 3)]}) # {1: 1, 2: False, 3: 3}集合推导式中若出现重复元素取第一个,与集合添加重复元素逻辑一致
c1, c2 = tuple([1, 2, 3]), tuple([1, 2, 3]) print(c1 is c2, c1 == c2, id(c1), id(c2)) # False True 2813361110080 2813361109888 a = {string for string in ["AAA", "BBB", "CCC", c1, c2]} print(a, type(a)) # {'AAA', 'BBB', 'CCC', (1, 2, 3)} <class 'set'> print([id(i) for i in a][3]) # 2813361110080
生成器表达式
生成器表达式并非元组表达式,其表达式的返回值为一个生成器对象。
生成器表达式与推导表达式相比:
- 生成器表达式返回的生成器是惰性的,生成器对象并未计算实际结果,而是等到需要时再计算,推导式直接返回的是计算结果,相对而言,一些场景下可以基于生成器表达式节省内存
- 对生成器表达式的迭代只能从头到尾进行一次,第二次为空容器,而推导式直接返回的结果,可以任意迭代
a = (string for string in ["AAA", "BBB", "CCC"])
print(a, type(a)) # <generator object <genexpr> at 0x000001B104992DD0> <class 'generator'>
print([string for string in a]) # ['AAA', 'BBB', 'CCC']
print([string for string in a]) # []
print([i for i in range(10 ** 6)].__sizeof__()) # 8448712
print((i for i in range(10 ** 6)).__sizeof__()) # 96
print([i for i in [0] * 10 ** 6].__sizeof__()) # 8448712
print((i for i in [0] * 10 ** 6).__sizeof__()) # 96
注:
空集合推导式结果类型是集合类型
print(type({string for string in []})) # <class 'set'>推导表达式或者生成器表达式在语法上是一种简写
# 一般形式 a = [] for string in ["AaA", "bBB", "cCC"]: for c in string: if c in ["a", 'b', 'c']: a.append(c) print(a) # ['a', 'b', 'c'] # 上层代码在前,下层代码在后 print([c for string in ["AaA", "bBB", "cCC"] for c in string if c in ["a", 'b', 'c']]) # ['a', 'b', 'c']