Python中如何区分Generator expression(生成器表达式)与其他方法
生成器表达式的区分方法
首先明确结论:不是所有被()包裹的表达式都是生成器表达式,小括号只是生成器表达式的外层标识之一,核心判断依据是语法结构,而不是是否存在小括号。
生成器表达式的核心特征
生成器表达式的固定语法结构为:
(输出表达式 for 迭代变量 in 可迭代对象 [if 过滤条件])
只要符合上述结构的表达式,不管是单独赋值还是作为函数参数,都属于生成器表达式:
- 单独使用时必须包裹小括号,例如你给出的示例:
此时G = (x**2 for x in range(4))G的类型为generator,支持__next__()调用、迭代遍历等操作。 - 当生成器表达式作为函数的唯一参数时,语法允许省略外层小括号,例如你给出的示例:
这种写法只是语法糖,本质还是传入了生成器对象作为参数。# 等价于 ''.join((x.upper() for x in 'aaa,bbb,ccc'.split(','))) ''.join(x.upper() for x in 'aaa,bbb,ccc'.split(',')) # 等价于 sum((x**2 for x in range(4))) sum(x**2 for x in range(4))
注:你给出的赋值示例
a,b,c = (x + '\n' for x in 'aaa,bbb'ccc'.split(','))存在语法错误,字符串'aaa,bbb'ccc'多了一个单引号,修正后应为a,b,c = (x + '\n' for x in 'aaa,bbb,ccc'.split(','))。
和其他带小括号的语法的区分方式
只要不符合上述生成器语法结构的小括号用法,都不属于生成器表达式,常见的非生成器小括号场景包括:
- 普通函数/方法调用:比如
range(4)、str(123),小括号内是函数的参数列表,没有for/in构成的迭代结构,range本身是Python内置的不可变序列类型,不是生成器。 - 调整运算优先级的小括号:比如
(1 + 2) * 3,小括号仅用来改变运算顺序,没有迭代结构。 - 元组字面量:比如
(1, "a", True),小括号内是逗号分隔的普通表达式,没有for/in结构。
如果拿不准可以直接用type()函数验证:
print(type((x**2 for x in range(4)))) # 输出 <class 'generator'> print(type(range(4))) # 输出 <class 'range'> print(type((1+2)*3)) # 输出 <class 'int'>
根据返回的类型即可100%准确区分。
内容的提问来源于stack exchange,提问作者Anurag Gupta
相关产品推荐
相关产品推荐

