# Quickstart¶

## What is an “indexed” priority queue?¶

A priority queue allows you to serve or retrieve items in a prioritized fashion. A priority queue supports inserting elements with priorities, and removing or peeking at the top priority element. The vanilla priority queue interface can be extended to support random access, insertion, removal and changing the priority of any element in the queue. An *indexed* priority queue does these latter operations efficiently.

The priority queue is implemented as a binary heap of (key, priority value) pairs, which supports:

- O(1) search for the item with highest priority
- O(log n) removal of the item with highest priority
- O(log n) insertion of a new item

An internal index maps elements to their location in the heap and is kept up to date as the heap is manipulated. As a result, pqdict also supports:

- O(1) lookup of any item by key
- O(log n) removal of any item
- O(log n) updating of any item’s priority level

Indexed priority queues are useful in applications where priorities of already enqueued items may frequently change (e.g., schedulers, optimization algorithms, simulations, etc.).

## Usage¶

The default heap is a min-heap, meaning **smaller** values give an item **higher** priority.

```
>>> from pqdict import pqdict
>>> pq = pqdict({'a':3, 'b':5, 'c':8})
>>> list(pq.popkeys())
['a', 'b', 'c']
```

To create a max-heap instead (**larger** values give **higher** priority), pass in the option `reverse=True`

.

```
>>> from pqdict import pqdict
>>> pq = pqdict({'a':3, 'b':5, 'c':8}, reverse=True)
>>> list(pq.popkeys())
['c', 'b', 'a']
```

Alternatively, you can use the alias functions `minpq()`

and `maxpq()`

.

```
>>> from pqdict import minpq
>>> pq = minpq(a=3, b=5, c=8)
```

By default, items are ordered by **value**. Analogous to the built-in `sorted()`

, you can provide a **priority key function** to transform the values for sorting.

```
>>> from pqdict import pqdict
>>> pq = pqdict({'a':(2,3), 'b':(8,5), 'c':(10,8)}, key=lambda x: x[1])
```

Views and regular iteration don’t affect the heap, but the output is **unsorted**. This applies to `pq.keys()`

, `pq.values()`

, `pq.items()`

and using `iter()`

(e.g., in a for loop).

```
queue = pqdict({'Alice':1, 'Bob':2})
for customer in queue:
serve(customer) # Bob may be served before Alice!
```

```
>>> list(pqdict({'a': 1, 'b': 2, 'c': 3, 'd': 4}).keys())
['a', 'c', 'b', 'd']
```

“Heapsort iterators” output data in **descending order** of priority by removing items from the collection. The following methods return heapsort iterators: `pq.popkeys()`

, `pq.popvalues()`

, and `pq.popitems()`

.

```
for customer in queue.popkeys():
serve(customer) # Customer satisfaction guaranteed :)
# queue is now empty
```

`pqdict`

supports all Python dictionary methods...

```
>>> from pqdict import pqdict
>>> pq = pqdict({'a':3, 'b':5, 'c':8})
>>> pq['d'] = 6.5
>>> pq['e'] = 2
>>> pq['f'] = -5
>>> 'f' in pq
True
>>> pq['f']
-5
>>> pq.pop('f')
-5
>>> 'f' in pq
False
>>> del pq['e']
>>> pq.get('e', None)
None
```

...and exposes a priority queue API.

```
>>> pq.top()
'c'
>>> pq.topitem()
('c', 1)
# manual heapsort...
>>> pq.pop() # no args
'c'
>>> pq.popitem()
('a', 3)
>>> pq.popitem()
('b', 5)
>>> pq.popitem()
('d', 6.5)
>>> pq.popitem() # ...and we're empty!
KeyError
```

Note

**Value mutability**. If you use mutable objects as values in a `pqdict`

, changes to the state of those objects can break the priority queue. If this does happen, the data structure can be repaired by calling `pq.heapify()`

. (But you probably shouldn’t be using mutable values in the first place.)

Note

**Custom precedence function**. The only difference between a min-pq and max-pq is that precedence of items is determined by comparing priority keys with the builtin `<`

and `>`

operators, respectively. If you would like to further customize the way items are prioritized, you can pass a boolean function `precedes(pkey1, pkey2)`

to the initializer.

The module functions `nsmallest`

and `nlargest`

work like the same functions in `heapq`

but act on mappings instead of sequences, sorting by value:

```
>>> from pqdict import nlargest
>>> billionaires = {'Bill Gates': 72.7, 'Warren Buffett': 60.0, ...}
>>> top5_names = nlargest(5, billionaires)
```

## License¶

This module is released under the MIT license. The augmented heap implementation was adapted from the `heapq`

module in the Python standard library, which was written by Kevin O’Connor and augmented by Tim Peters and Raymond Hettinger.

## Documentation¶

Documentation is available at http://pqdict.readthedocs.org/en/latest/.