Python 列表上的生成器与链接生成器和内存消耗?

Python 列表上的生成器与链接生成器和内存消耗?,python,generator,Python,Generator,有人能解释一下这些例子中的生成器是如何工作的吗 在本例中,来自 当我们像这样链接生成器时,在执行sum()之前,除了代码对象创建之外,还会发生任何实际工作吗 为什么我们需要执行line.split(无,1)[1] 和int(x)分开-这样做有好处吗 在本例中(x*x表示范围内的x(1100000000)) 在Python 2中,当解释器对该表达式求值时,是否计算了范围(1100000000) 这是在该语句期间还是在生成器的第一次运行期间发生的 这在Python3中有什么不同吗 我产生这种怀疑的原

有人能解释一下这些例子中的生成器是如何工作的吗

在本例中,来自

  • 当我们像这样链接生成器时,在执行sum()之前,除了代码对象创建之外,还会发生任何实际工作吗
  • 为什么我们需要执行line.split(无,1)[1] 和int(x)分开-这样做有好处吗
  • 在本例中(x*x表示范围内的x(1100000000))

  • 在Python 2中,当解释器对该表达式求值时,是否计算了范围(1100000000)
  • 这是在该语句期间还是在生成器的第一次运行期间发生的
  • 这在Python3中有什么不同吗
  • 我产生这种怀疑的原因是这个片段:

    def foo():
        for each in range(1,100000):
          yield each
    
    a = foo()
    
    # Here range is not evaluated until generator is run or just 
    # before first yield is hit which is expected.
    
    a=(x for x in range(1,100000)) 
    
    # I thought also does exact thing as that function and it i is a 
    # syntactic sugar for a=foo() which also yields a generator object.
    

    与列表或场景相比,使用生成器有什么优势吗?在列表或场景中,这样做更为实际。

    1.当我们像这样链接生成器时,在执行sum()之前,是否会发生任何实际工作

    生成器表达式返回按需生成结果的对象,而不是生成 结果列表,所以您的答案是否定的(但这仍然取决于您对实际工作的平均值)

    2.为什么我们需要分别执行
    line.split(None,1)[1]
    int(x)
    ——这样做有好处吗

    它只是使您的代码更具可读性并增加灵活性(基于您对该表达式的操作),您可以在一行中完成:

    在本例中(x*x表示范围内的x(1100000000))

    3.Python 2中是否计算了范围(1100000000)

    是的,在Python2中可以使用返回迭代器的
    xrange

    4.如果是,是在本声明期间还是在发电机首次运行期间

    5.这与Python 3中的不同吗

    在Python3中,许多内置函数返回一个迭代器,如
    open
    range

    对于您的第四个问题和您在评论中的问题,我认为这部分内容可能会有所帮助:

    生成器表达式:迭代器满足理解 在Python的所有最新版本中,迭代器和列表理解的概念都是 结合了语言的一个新特性,生成器表达式。从句法上说,gen- 运算符表达式与普通的列表理解类似,但它们包含在 用括号代替方括号:

    >>> [x ** 2 for x in range(4)]
    [0, 1, 4, 9] # List comprehension: build a list
    >>> (x ** 2 for x in range(4))
    <generator object at 0x011DC648> # Generator expression: make an iterable
    
    列表理解等值 但是,在操作上,生成器表达式与构建表达式非常不同 在内存中的结果列表中,它们返回一个生成器对象,该对象反过来支持 迭代协议,在任何迭代上下文中一次生成一个结果列表:

    >>> G = (x ** 2 for x in range(4))
    >>> next(G)
    0
    >>> next(G)
    1
    >>> next(G)
    4
    >>> next(G)
    9
    >>> next(G)
    Traceback (most recent call last):
    ...more text omitted...
    StopIteration
    
    我们通常不会在生成器的引擎盖下看到下一个迭代器- 按此键是因为for循环会自动为我们触发它:

    >>> for num in (x ** 2 for x in range(4)):
    ...
    print('%s, %s' % (num, num / 2.0))
    ...
    0, 0.0
    1, 0.5
    4, 2.0
    9, 4.5
    
    正如我们已经了解到的,每个迭代上下文都会这样做,包括sum、map和 已排序的内置函数;列表理解;以及我们学习的其他迭代上下文 关于第14章中的,如any、all和list内置函数。 请注意,在生成器表达式周围不需要括号(如果有) 包含在其他括号中的唯一项,如函数调用的项。额外津贴- 但是,在第二次调用排序时需要这些:

    >>> sum(x ** 2 for x in range(4))
    14
    >>> sorted(x ** 2 for x in range(4))
    [0, 1, 4, 9]
    >>> sorted((x ** 2 for x in range(4)), reverse=True)
    [9, 4, 1, 0]
    >>> import math
    >>> list( map(math.sqrt, (x ** 2 for x in range(4))) )
    [0.0, 1.0, 2.0, 3.0]
    
    生成器表达式主要是一种内存空间优化,它们不会重复- 要求同时构建整个结果列表,如方括号中的列表 理解才是。它们在实践中也可能运行得稍慢,因此它们可能是 最好仅用于非常大的结果集。关于per的更权威的声明-
    不过,性能将不得不等待我们在本章后面编写的计时脚本。

    1.当我们像这样链接生成器时,在我们执行sum()之前,是否会发生任何实际的工作

    生成器表达式返回按需生成结果的对象,而不是生成 结果列表,所以您的答案是否定的(但这仍然取决于您对实际工作的平均值)

    2.为什么我们需要分别执行
    line.split(None,1)[1]
    int(x)
    ——这样做有好处吗

    它只是使您的代码更具可读性并增加灵活性(基于您对该表达式的操作),您可以在一行中完成:

    在本例中(x*x表示范围内的x(1100000000))

    3.Python 2中是否计算了范围(1100000000)

    是的,在Python2中可以使用返回迭代器的
    xrange

    4.如果是,是在本声明期间还是在发电机首次运行期间

    5.这与Python 3中的不同吗

    在Python3中,许多内置函数返回一个迭代器,如
    open
    range

    对于您的第四个问题和您在评论中的问题,我认为这部分内容可能会有所帮助:

    生成器表达式:迭代器满足理解 在Python的所有最新版本中,迭代器和列表理解的概念都是 结合了语言的一个新特性,生成器表达式。从句法上说,gen- 运算符表达式与普通的列表理解类似,但它们包含在 用括号代替方括号:

    >>> [x ** 2 for x in range(4)]
    [0, 1, 4, 9] # List comprehension: build a list
    >>> (x ** 2 for x in range(4))
    <generator object at 0x011DC648> # Generator expression: make an iterable
    
    列表理解等值 但是,在操作上,生成器表达式与构建表达式非常不同 在内存中的结果列表中,它们返回一个生成器对象,该对象反过来支持 迭代协议,在任何迭代上下文中一次生成一个结果列表:

    >>> G = (x ** 2 for x in range(4))
    >>> next(G)
    0
    >>> next(G)
    1
    >>> next(G)
    4
    >>> next(G)
    9
    >>> next(G)
    Traceback (most recent call last):
    ...more text omitted...
    StopIteration
    
    我们通常不会在生成器的引擎盖下看到下一个迭代器- 按此键是因为for循环会自动为我们触发它:

    >>> for num in (x ** 2 for x in range(4)):
    ...
    print('%s, %s' % (num, num / 2.0))
    ...
    0, 0.0
    1, 0.5
    4, 2.0
    9, 4.5
    
    正如我们已经了解到的,每个迭代上下文都会这样做,包括sum、map和 已排序的内置函数;列表理解;以及我们学习的其他迭代上下文 关于第14章,比如任何,所有,