Python生成器表达式

示例

生成器表达式与列表推导非常相似。主要区别在于它不会立即创建完整的结果集;它创建了一个生成器对象,然后可以对其进行迭代。

例如,请参见以下代码中的区别:

# 清单理解

[x**2 for x in range(10)]

# 输出:[0、1、4、9、16、25、36、49、64、81]

Python 2.x 2.4
# 生成器理解

(x**2 for x in xrange(10))

# Output: <generator object <genexpr> at 0x11b4b7c80>

这是两个非常不同的对象:

  • 列表推导返回一个list对象,而生成器推导返回一个对象generator。

  • generator无法为对象建立索引,而是无法使用该next函数按顺序获取项目。

注意:我们使用xrange它是因为它也会创建一个生成器对象。如果我们使用范围,则会创建一个列表。此外,xrange仅在更高版本的python 2中存在。在python 3中,range仅返回生成器。有关更多信息,请参见range和xrange函数之间差异示例。


Python 2.x 2.4
g = (x**2 for x in xrange(10))

print(g[0])

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

TypeError: 'generator' object has no attribute '__getitem__'


g.next()  # 0

g.next()  # 1

g.next()  # 4

...

g.next()  # 81

g.next()  # 引发StopIteration异常

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

StopIteration

Python 3.x 3.0

注:该功能应该被取代,并用自和Python 3中并不存在。g.next()next(g)xrangerangeIterator.next()xrange()


尽管这两种方法都可以通过类似的方式进行迭代:

for i in [x**2 for x in range(10)]:

    print(i)

"""

Out:

0

1

4

...

81

"""

Python 2.x 2.4
for i in (x**2 for x in xrange(10)):

    print(i)

"""

Out:

0

1

4

.

.

.

81

"""


用例

生成器表达式是延迟计算的,这意味着它们仅在迭代生成器时才生成并返回每个值。在遍历大型数据集时,这通常很有用,避免了在内存中创建数据集副本的需要:

for square in (x**2 for x in range(1000000)):

    #做点什么

另一个常见用例是避免不必要地遍历整个可迭代对象。在此示例中,每次的迭代都从远程API检索项目get_objects()。可能存在成千上万个对象,必须逐一检索它们,而我们只需要知道是否存在与模式匹配的对象即可。通过使用生成器表达式,当我们遇到与模式匹配的对象时。

def get_objects():

    """Gets objects from an API one by one"""

    while True:

        yield get_next_item()

def object_matches_pattern(obj):

    # 执行潜在的复杂计算

    return matches_pattern

def right_item_exists():

    items = (object_matched_pattern(each) for each in get_objects())

    for item in items:

        if item.is_the_right_one:

            return True

    return False

           

以上是 Python生成器表达式 的全部内容, 来源链接: utcz.com/z/315719.html

回到顶部