大家讲道理2017-04-17 17:02:37
Iterator
and Generator
are two concepts. Conceptually, they have no overlap, that is, there is no similarity. 迭代器
与生成器
是两个概念,在概念上,他们没有重叠,也就是说,没有相同点。
我简单概述一下:
迭代器,其实就是可以用来迭代
的容器
,比如,一个list,tuple等.
生成器,这里的生成
指得是它可以产生迭代器
.
下面是demo:
foods = ['banana', 'hot dog', 'dumpling']
for food in foods:
print food
这里的foods
就是一个迭代器.
def send_file(file_path, size):
with open(file_path) as f:
block = f.read(BLOCK_SIZE)
while block:
yield block
block = f.read(BLOCK_SIZE)
这是一个生成器
,注意,生成器
的重点就是yield
,这里的block
就是生成器每次生成的值,可以暂时理解为相当于迭代器
中的单个元素,比如foods
中的banana
元素,而生成器的主要作用就是把大内存占用数据分次写入内存
container
that can be used to iterate
, such as a list, tuple, etc.🎜Generate
means that it can generate Iterator
.🎜foods
here is an iterator.🎜
rrreee
🎜This is a generator
. Note that the focus of generator
is yield
, and the block
here is the generator. The value generated each time can be temporarily understood as equivalent to a single element in Iterator
, such as the banana
element in foods
, and the generator The main function is to write large memory occupied data into the memory in batches
. The advantage of this is that it does not need to read all the data into the program at once to occupy a large amount of memory, and it can be used without affecting the use. In this case, it prevents memory leaks, thereby giving program users a better experience and making your code more elegant (ge).🎜
🎜As for the usage scenarios, it has actually been mentioned above. If you want to know more specifically, then like me:)🎜阿神2017-04-17 17:02:37
In python, you can place the iterator in the for statement and add the iterator feature to an object to meet the above requirements; here is an example of mine. We usually need to use memory mapped files to open a large file. However, the standard mmap object does not support iteration, which means that the following code cannot be executed:
for line in mmap.open(file_name):
print line
If you want to achieve this effect, you need to use iterators, see the iter and next functions below;
class Mmap(object):
__slots__ = ['os', 'mmap', 'handler', 'mhandler']
def __init__(self, fname):
self.os = __import__('os', fromlist=['path'])
self.mmap = __import__('mmap')
assert self.os.path.exists(fname), 'File(%s) Not Exists !' % fname
self.handler = open(fname)
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
self.mhandler.close()
self.handler.close()
del self.os
del self.mmap
class Reader(Mmap):
'''使用mmap打开文件,并添加iterable特性'''
def __init__(self, fname):
super(Reader, self).__init__(fname)
self.mhandler = self.mmap.mmap(self.handler.fileno(), 0, prot=self.mmap.PROT_READ)
def __iter__(self):
return self
def next(self):
line = self.mhandler.readline()
if line:
return line
else:
raise StopIteration
if __name__ == '__main__':
with Reader('./demo/simple.dat') as f: #现在就可以了
for line in f:
print line.strip()
The application scenarios of generators are mainly in lazy evaluation and data generation. Assume that in a certain logic, you need 0~3 million random numbers, you have two options:
Generate 3 million random numbers at one time and place them in a list or somewhere.
Temporarily generate one each time you need (use generator)
def next_random_num():
while True:
yield random.randint()
for line in open('txtfile'):
print next_random_num + int(line.strip())
In the above code, how many random numbers are temporarily generated according to the number of lines in the file;