Слить или выбросить генератор без зацикливания? - PullRequest
3 голосов
/ 21 февраля 2012

В обработчике исключений для процесса в стиле CSP мне нужно прочитать и отбросить все содержимое канала, чтобы разрешить другим блокирующим процессам отправить его на выполнение.Интерфейс представляет генератор для получения, есть ли более быстрый способ потреблять и отбрасывать все содержимое генератора, чем следующий?

for _ in chan:
    pass

Ответы [ 3 ]

5 голосов
/ 21 февраля 2012

Есть способ, который немного быстрее:

collections.deque(chan, maxlen=0)

Однако ваш код проясняет намерение, поэтому вам следует оценить, есть ли заметная разница. Я почти всегда предпочитаю твой код.

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

Редактировать : Вот несколько простых моментов времени:

In [1]: import collections

In [2]: a = range(100000)

In [3]: timeit reduce(lambda _, __: None, a)
100 loops, best of 3: 13.5 ms per loop

In [4]: timeit for dummy in a: pass
1000 loops, best of 3: 1.75 ms per loop

In [5]: timeit collections.deque(a, maxlen=0)
1000 loops, best of 3: 1.51 ms per loop
1 голос
/ 21 февраля 2012

Я начал использовать deque, который я могу использовать в случае необходимости:

do_all = deque(maxlen=0).extend

Тогда я могу использовать выражения генератора, используя:

do_all(poly.draw() for poly in model.polys)
0 голосов
/ 21 февраля 2012

Вы можете попробовать:

reduce(lambda _, __: None, chan)

Но, честно говоря, я не думаю, что вы добьетесь большего успеха, чем простой цикл.«канал» предполагает ввод / вывод, который все равно будет узким местом.

...