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

Nis*_*ant 1 python generator

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

在这个例子中来自http://www.dabeaz.com/generators/index.html

wwwlog = open("access-log")
bytecolumn = (line.rsplit(None,1)[1] for line in wwwlog)
bytes = (int(x) for x in bytecolumn if x != '-')
print "Total", sum(bytes)
Run Code Online (Sandbox Code Playgroud)
  1. 当我们链接这样的生成器时,除了代码对象创建之外,还有什么真正的工作发生,直到我们做sum()?
  2. 为什么我们需要分别执行line.split(None,1)[1]和int(x) - 这样做有什么好处?

在这个例子中(x*x代表范围内的x(1,100000000))

  1. 当解释器评估此表达式时,是否在Python 2中计算了范围(1,100000000)?
  2. 这是在本声明中还是在第一次运行发生器期间发生的
  3. 这在Python 3中有什么不同吗?

我有这个疑问的原因是这个片段:

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.
Run Code Online (Sandbox Code Playgroud)

使用生成器超过列表或场景更有实际可行吗?

rlm*_*lms 5

  1. 生成器是懒惰的,所以在迭代它们之前没有任何反应(例如sum).
  2. 它只是使它更具可读性.你可以这样写,如果你想: bytes = (int(x) for x in (line.rsplit(None,1)[1] for line in wwwlog) if x != '-')
  3. 是的,在Python 2中range返回一个列表,你需要xrange生成一个类似生成器的对象.
  4. 它是在迭代生成器时计算的,直到那时才进行任何操作.
  5. 是的,在Python 3中range表现得像Python 2 xrange.同样的事情发生在像map和的其他功能上filter.

生成器的主要优点是它们不会立即存储它们的全部内容.它们的主要缺点是你只能迭代它们一次.