搜尋

首頁  >  問答  >  主體

语法 - python的生成器和迭代器问题

ringa_leeringa_lee2823 天前665

全部回覆(2)我來回復

  • 大家讲道理

    大家讲道理2017-04-17 17:02:37

    迭代器生成器是兩個概念,在概念上,他們沒有重疊,也就是說,沒有相同點迭代器生成器是两个概念,在概念上,他们没有重叠,也就是说,没有相同点

    我简单概述一下:

    • 迭代器,其实就是可以用来迭代容器,比如,一个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元素,而生成器的主要作用就是把大内存占用数据分次写入内存

    我簡單概述一下:

    • 迭代器,其實就是可以用來迭代容器,比如,一個list,tuple等.🎜
    • 🎜產生器,這裡的產生指得是它可以產生迭代器.🎜
    🎜下面是demo:🎜 rrreee 🎜這裡的foods就是一個迭代器.🎜 rrreee 🎜這是一個生成器,注意,生成器的重點就是yield,這裡的block就是生成器每次產生的值,可以暫時理解為相當於迭代器中的單一元素,例如foods中的banana元素,而產生器的主要作用就是把大內存佔用數據分次寫入內存,這樣做得好處就是可以不用一次性將所有數據讀入到程序中佔用大量內存,並且可以在不影響使用的情況下,防止記憶體洩露,從而讓程式使用者有更好的體驗,也會讓你的程式碼更(you)優(bi)雅(ge).🎜 🎜關於使用場景,其實上面已經提到了,如果想知道更具體的,那麼,讚我:)🎜

    回覆
    0
  • 阿神

    阿神2017-04-17 17:02:37

    在python中,你可以將迭代器放置在for語句中,將一個物件添加迭代器特性就可以滿足上面的需求;這裡是我的一個例子,我們通常需要使用內存映射文件方式打開一個大文件,但是標準的mmap物件不支援迭代,也就是說像下面的程式碼是不能執行的:

    for line in mmap.open(file_name):
        print line

    如果你希望可以達到這樣的效果就需要藉助與迭代器, 參見下面的iter和next函數;

    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() 

    關於生成器,你需要用到yield或生成器表達式;

    生成器的應用場景主要在懶求值和資料生成,假設某個邏輯中,你需要0~300w個隨機數,你有兩種選擇:

    1. 一次產生300w隨機數,然後放置在list或某個地方。

    2. 每次需要時臨時產生一個(使用生成器)

    def next_random_num():
        while True:
            yield random.randint()
            
    for line in open('txtfile'):
        print next_random_num + int(line.strip())

    在上面程式碼中,檔案有多少行則暫時產生多少個隨機數;

    回覆
    0
  • 取消回覆