extracting a heapq in a for loop - there must be more elegant solution

Duncan Booth duncan.booth at invalid.invalid
Tue Dec 3 08:06:05 EST 2013


Helmut Jarausch <jarausch at igpm.rwth-aachen.de> wrote:

> Hi,
> 
> I'd like to extracted elements from a heapq in a for loop.
> I feel my solution below is much too complicated.
> How to do it more elegantly? 
> I know I could use a while loop but I don't like it.
> 
> Many thanks for some lessons in Python.
> 
> Here is my clumsy solution
> 
> from heapq import heappush, heappop
> # heappop raises IndexError if heap is empty
> 
> H=[]
> for N in 'H','C','W','I' :
>   heappush(H,N)
> 
> # how to avoid / simplify the following function
> 
> def in_sequence(H) :
>   try :
>     while True :
>       N= heappop(H)
>       yield N
>   except IndexError :
>     raise StopIteration
> 
> # and here the application:
> 
> for N in in_sequence(H) :
>   print(N)
> 

If all you want to do is pull all of the elements out of the heap in 
order, you would probably be better off just doing:

for N in sorted(H):
    print(N)

Heaps are mostly useful if you want only some of the elements, or if you 
are continually producing more elements while also processing the 
smallest ones.

However, if you really wnt to do this:

    for N in iter(lambda: heappop(H) if H else None, None):
        print(N)

will work so long as H cannot contain None. If it can just replace both 
occurences of None with some other sentinel:

    sentinel = object()
    for N in iter(lambda: heappop(H) if H else sentinel, sentinel):
        print(N)


Alternatively your 'in_sequence' function would look better without the 
exception handling:

def in_sequence(H) :
    while H:
        yield heappop(H)

-- 
Duncan Booth



More information about the Python-list mailing list