Drain or discard a generator without looping?

后端 未结 3 895
栀梦
栀梦 2021-01-14 13:58

In an exception handler for a CSP style process, I need to read and discard the entire contents of a channel in order to allow other processes that are blocking to send to i

相关标签:
3条回答
  • 2021-01-14 14:26

    There is a way that is slightly faster:

    collections.deque(chan, maxlen=0)
    

    Your code makes the intention much clearer, though, so you should measure if there is a discernible difference. I'd almost always prefer your code.

    (I'd never use _ as a variable name, though. It tends to confuse people, clashes with _ in the interactive shell and with the common gettext alias.)

    Edit: Here are some simple timings:

    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
    
    0 讨论(0)
  • 2021-01-14 14:28

    I've started using a deque that I can reuse if need be:

    do_all = deque(maxlen=0).extend
    

    Then I can consume generator expressions using:

    do_all(poly.draw() for poly in model.polys)
    
    0 讨论(0)
  • 2021-01-14 14:34

    You might try:

    reduce(lambda _, __: None, chan)
    

    But honestly I don't think you're going to do much better than the plain loop. "channel" suggests I/O which is going to be the bottleneck anyway.

    0 讨论(0)
提交回复
热议问题