Где Вы используете функцию генераторов в своем коде Python?

Я изучил функцию генераторов, и я думаю, что получил ее, но я хотел бы понять, где я мог применить ее в своем коде.

Я имею в виду следующий пример, я прочитал в "Python существенную ссылочную" книгу:

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

У Вас есть какой-либо другой эффективный пример, где генераторы являются лучшим инструментом для задания как хвост-f?

Как часто Вы используете функцию генераторов и в котором виде functionality\part программы Вы обычно применяете ее?

5
задан systempuntoout 29 March 2010 в 06:58
поделиться

4 ответа

Я часто использую их, когда внедряю сканеры (токенизаторы) или перебираю контейнеры данных.

Изменить: вот демонстрационный токенизатор, который я использовал для программы выделения синтаксиса 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)
>>> 
6
ответ дан 18 December 2019 в 14:44
поделиться

В целом, чтобы отделить сбор данных (который может быть сложным) от потребления. В частности:

  • для объединения результатов нескольких запросов с b-деревом - часть db генерирует и выполняет запросы выдают -ing записи из каждого из них, потребитель видит только поступающие отдельные элементы данных.
  • буферизация (упреждающее чтение) - генератор выбирает данные блоками и выдает отдельные элементы из каждого блока. Опять же, потребитель отделен от кровавых подробностей.

Генераторы также могут работать как сопрограммы. Вы можете передать данные в их, используя nextval = g.next (data) на стороне потребителя и data = yield (nextval) на стороне генератора. . В этом случае генератор и его потребитель меняют местами значения. Вы даже можете заставить yield генерировать исключение в контексте генератора: g.throw (exc) делает это.

1
ответ дан 18 December 2019 в 14:44
поделиться

Во всех случаях, когда у меня есть алгоритмы, считывающие что-либо, я использую исключительно генераторы.

Почему?

Слои в правилах фильтрации, отображения и сокращения намного проще в контексте нескольких генераторов.

Пример:

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

Я предпочитаю использовать много небольших генераторов, чтобы небольшое изменение не нарушило всю цепочку процесса.

2
ответ дан 18 December 2019 в 14:44
поделиться

Каждый раз, когда ваш код генерирует неограниченное количество значений или, в более общем смысле, если слишком много памяти будет израсходовано путем создания всего списка вначале.

Или, если есть вероятность, что вы не перебираете весь сгенерированный список (а список очень большой). Я имею в виду, что нет смысла сначала генерировать каждое значение (и ждать генерации), если оно не используется.

Моя последняя встреча с генераторами произошла, когда я реализовал линейную рекуррентную последовательность (LRS), например, последовательность Фибоначчи.

4
ответ дан 18 December 2019 в 14:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: