为了更好地理解关键字yield
的用法,首先需要理解迭代器(iterator)与生成器(generator)的区别。当创建列表中的元素时,我们可以使用for
循环:
>>> myIterator = [x*x for x in range(3)]>>> print(myIterator)[0, 1, 4]
因此我们称列表是可迭代的(iterable)。但是基于这种方法逐次访问列表中的元素时,需要首先将包含所有元素的列表创建并保存,当元素数量过多时可能造成内存空间的利用效率下降。因此考虑只进行一次迭代的生成器,并不在访问元素之前将所有元素值存储在内存空间,而是在迭代过程中生成要访问的元素,并且访问过的元素就不会再存储在生成器所占的内存空间中。
>>> myGenerator = (x*x for x in range(3))>>> print(myGenerator)<generator object <genexpr> at 0x000001F67D449518>>>> for i in myGenerator: print(i)014>>> print(myGenerator)<generator object <genexpr> at 0x000001F67D449518>>>> for i in myGenerator: print(i)>>>
上述代码首先创建生成器对象,使用for
循环迭代访问生成器中的每一个元素时,可以看到进行一次迭代后生成器就变为空。也可以将生成器对象转换为列表对象,生成器在访问一次之后变为空就可以更明显地看出来:
>>> myGenerator = (x*x for x in range(3))>>> print(myGenerator)<generator object <genexpr> at 0x000001B3A48DED00>>>> print(list(myGenerator))[0, 1, 4]>>> print(list(myGenerator))[]
而关键字yield
的作用类似于return
,但返回的是一个生成器对象,注意代码示例表示返回的生成器的元素为i*i
:
>>> def createGenerator(): for i in range(3): yield i*i>>> mygenerator = createGenerator()>>> print(mygenerator)<generator object createGenerator at 0x000001F67D449518>>>> for item in mygenerator: print(item)014>>>
在nlp相关应用中,可能在读取数据集时会使用到yield
关键字以节省内存开销,代码示例表示返回的生成器中的元素是列表:
>>> def read_dataset(file): for line in file: yield [word for word in line.split(" ")]>>> dataset = ["hello world", "i love china", "are you ok"]>>> train = read_dataset(dataset)>>> print(train)<generator object read_dataset at 0x000001F67D46CD00>>>> print(list(train))[['hello', 'world'], ['i', 'love', 'china'], ['are', 'you', 'ok']]>>> print(list(train))[]
来源:http://www.icode9.com/content-1-73501.html
联系客服