社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

在Python代码中,您在哪里使用生成器特性?

systempuntoout • 5 年前 • 1613 次点击  

我已经学习了生成器特性,我想我已经掌握了它,但是我想知道在哪里可以将它应用到我的代码中。

我在“python-essential-reference”一书中读到了以下示例:

# tail -f
 def tail(f):
  f.seek(0,2) 
  while True:
   line = f.readline() 
   if not line: 
     time.sleep(0.1)
     continue
   yield line

你有没有其他有效的例子,发电机是最好的工具,如tail-f?

您多久使用一次生成器功能,以及通常在程序的哪种功能\部分中应用它?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/38655
 
1613 次点击  
文章 [ 4 ]  |  最新文章 5 年前
Rafał Dowgird
Reply   •   1 楼
Rafał Dowgird    15 年前

一般来说,将数据获取(可能很复杂)与消费分开。特别地:

  • 要连接多个B树查询的结果,db部分将生成并执行查询 yield -通过记录,消费者只看到单个数据项到达。
  • 缓冲(预读)-生成器获取块中的数据,并从每个块生成单个元素。同样,消费者与血淋淋的细节是分开的。

发电机也可以作为协同工作。你可以传递数据 进入之内 他们使用 nextval=g.next(data) 在“消费者”方面, data = yield(nextval) 在发电机侧。在这种情况下,发电机及其用户的“交换”值。你甚至可以 产量 在生成器上下文中引发异常: g.throw(exc) 就是这样。

S.Lott
Reply   •   2 楼
S.Lott    15 年前

在所有情况下,我都有读任何东西的算法,我只使用生成器。

为什么?

在多个生成器的上下文中,在过滤、映射和约简规则中进行分层要容易得多。

例子:

def discard_blank( source ):
    for line in source:
        if len(line) == 0:
            continue
        yield line

def clean_end( source ):
    for line in source:
        yield line.rstrip()

def split_fields( source ):
    for line in source;
        yield line.split()

def convert_pos( tuple_source, position ):
    for line in tuple_source:
        yield line[:position]+int(line[position])+line[position+1:]

with open('somefile','r') as source:
    data= convert_pos( split_fields( discard_blank( clean_end( source ) ) ), 0 )
    total= 0
    for l in data:
        print l
        total += l[0]
    print total

我的偏好是使用许多小的生成器,这样一个小的更改就不会破坏整个流程链。

Felix Kling
Reply   •   3 楼
Felix Kling    15 年前

每当您的代码生成 值的数量不受限制 或者更一般地说,如果 内存太多 首先会被生成整个列表所消耗。

或者如果你 不要 迭代 完整生成的列表 (而且名单很大)。我的意思是,如果没有使用每个值,就没有必要先生成它(并等待生成)。

我最近遇到的生成器是当我实现一个线性循环序列(LRS)时,比如斐波那契序列。

Nick Dandoulakis
Reply   •   4 楼
Nick Dandoulakis    15 年前

当我实现扫描器(标记化器)或在数据容器上迭代时,我经常使用它们。

编辑:这是一个用于C++语法高亮程序的演示记录器:

whitespace = ' \t\r\n'
operators = '~!%^&*()-+=[]{};:\'"/?.,<>\\|'

def scan(s):
    "returns a token and a state/token id"
    words = {0:'', 1:'', 2:''} # normal, operator, whitespace
    state = 2 # I pick ws as first state
    for c in s:
        if c in operators:
            if state != 1:
                yield (words[state], state)
                words[state] = ''
            state = 1
            words[state] += c
        elif c in whitespace:
            if state != 2:
                yield (words[state], state)
                words[state] = ''
            state = 2
            words[state] += c
        else:
            if state != 0:
                yield (words[state], state)
                words[state] = ''
            state = 0
            words[state] += c
    yield (words[state], state)

用法示例:

>>> it = scan('foo(); i++')
>>> it.next()
('', 2)
>>> it.next()
('foo', 0)
>>> it.next()
('();', 1)
>>> it.next()
(' ', 2)
>>> it.next()
('i', 0)
>>> it.next()
('++', 1)
>>>