python 是否在生成器对象上使用实习? (i for i in range(n)) 的奇怪行为
Does python use interning on generator objects? Weird behaviour with (i for i in range(n))
为什么这两个循环给出的结果不同? (是的,我知道第二个版本的风格很糟糕。但我仍然希望它能提供相同的输出。)
gen1 = range(3)
gen2 = range(3)
print("First attempt")
for i in gen1:
for j in gen2:
print(i,j)
gen1 = (i for i in range(3))
gen2 = (i for i in range(3))
print("Second attempt")
for i in gen1:
for j in gen2:
print(i,j)
使用 Python 3.6.9 输出(我用 Python 2.7.15 得到相同的结果):
First attempt
(0, 0)
(0, 1)
(0, 2)
(1, 0)
(1, 1)
(1, 2)
(2, 0)
(2, 1)
(2, 2)
Second attempt
(0, 0)
(0, 1)
(0, 2)
range
是它自己的类型。它是可迭代的,但不是 迭代器(或生成器)——您可以多次迭代它,每次创建独立的迭代器:
>>> r = range(2)
>>> list(r)
[0, 1]
>>> list(r)
[0, 1]
>>> next(r)
TypeError: 'range' object is not an iterator
生成器,与生成器表达式一样,是 迭代器。当你迭代它们时,你推进了它们。
>>> r = (1 + x for x in range(2))
>>> list(r)
[1, 2]
>>> list(r)
[]
>>> r = (1 + x for x in range(2))
>>> iter(r) is r
True
>>> next(r)
1
而且,明确回答第一个问题,此行为与实习无关。在 for i in gen1
循环的第一次迭代期间,消耗了 gen2
,因此剩余的迭代什么都不做。
为什么这两个循环给出的结果不同? (是的,我知道第二个版本的风格很糟糕。但我仍然希望它能提供相同的输出。)
gen1 = range(3)
gen2 = range(3)
print("First attempt")
for i in gen1:
for j in gen2:
print(i,j)
gen1 = (i for i in range(3))
gen2 = (i for i in range(3))
print("Second attempt")
for i in gen1:
for j in gen2:
print(i,j)
使用 Python 3.6.9 输出(我用 Python 2.7.15 得到相同的结果):
First attempt
(0, 0)
(0, 1)
(0, 2)
(1, 0)
(1, 1)
(1, 2)
(2, 0)
(2, 1)
(2, 2)
Second attempt
(0, 0)
(0, 1)
(0, 2)
range
是它自己的类型。它是可迭代的,但不是 迭代器(或生成器)——您可以多次迭代它,每次创建独立的迭代器:
>>> r = range(2)
>>> list(r)
[0, 1]
>>> list(r)
[0, 1]
>>> next(r)
TypeError: 'range' object is not an iterator
生成器,与生成器表达式一样,是 迭代器。当你迭代它们时,你推进了它们。
>>> r = (1 + x for x in range(2))
>>> list(r)
[1, 2]
>>> list(r)
[]
>>> r = (1 + x for x in range(2))
>>> iter(r) is r
True
>>> next(r)
1
而且,明确回答第一个问题,此行为与实习无关。在 for i in gen1
循环的第一次迭代期间,消耗了 gen2
,因此剩余的迭代什么都不做。