在生成器函数的整个生命周期中,需要存储Python 2 range()函数产生的庞大列表,是的,并且会占用内存.
如果可以根据需要计算生成器的结果,生成器函数可以提高内存效率,但是range()函数可以预先生成所有结果.
您可以计算下一个数字:
def function1():
i = 0
while i < HUGE_NUMBER:
yield i
i += 1
您会得到相同的结果,但是您不会一口气存储整个范围内的所有数字.本质上,这就是在xrange() object上循环执行的操作;它根据要求计算数字. (在Python 3中,xrange()替换了range()).
同样适用于您的功能3;您首先将整个文件读入字典,所以迭代时仍将其存储在内存中.无需仅将整个文件读入内存就可以随后产生每个元素.您可以只遍历文件并产生一行:
def function3(file):
seen = set()
with open(file, 'r') as f:
reader = csv.reader(f, delimiter = ' ')
for k, v in reader:
if k in seen:
# already seen
continue
seen.add(k)
yield k, v
这只会存储被视为避免重复的键(如字典那样),但不会存储值.当您遍历生成器时,内存会增加.如果重复不是问题,则可以完全省略对可见键的跟踪:
def function3(file):
with open(file, 'r') as f:
reader = csv.reader(f, delimiter = ' ')
for k, v in reader:
yield k, v
甚至
def function3(file):
with open(file, 'r') as f:
reader = csv.reader(f, delimiter = ' ')
return reader
毕竟读者是可迭代的.