API

This page contains auto-generated documentation from the bidict source code.

bidict

Efficient, Pythonic bidirectional map implementation and related functionality.

See https://bidict.readthedocs.io for comprehensive documentation.

class bidict.BidirectionalMapping[source]

Abstract base class for bidirectional mappings. Extends collections.abc.Mapping.

_subclsattrs

The attributes that __subclasshook__ checks for to determine whether a class is a subclass of BidirectionalMapping.

__inverted__()[source]

Get an iterator over the items in inv.

classmethod __subclasshook__(C)[source]

Check if C provides all the attributes in _subclsattrs.

Causes conforming classes to be virtual subclasses automatically.

inv

The inverse bidict.

class bidict.BidictBase(*args, **kw)[source]

Base class for all provided bidirectional map types.

Mutable and immutable bidict types extend this class, which implements all the shared logic. Users will typically only interact with subclasses of this class.

_fwd

The backing one-way dict for the forward items.

_inv

The backing one-way dict for inverse items.

_fwd_class

The Mapping type used for the backing _fwd dict.

_inv_class

The Mapping type used for the backing _inv dict.

_isinv

bool representing whether this bidict is the inverse of some other bidict which has already been created. If True, the meaning of _fwd_class and _inv_class is swapped. This enables the inverse of a bidict specifying a different _fwd_class and _inv_class to be passed back into its constructor such that the resulting copy has its _fwd_class and _inv_class set correctly.

_on_dup_key

DuplicationBehavior in the event of a key duplication.

_on_dup_val

DuplicationBehavior in the event of a value duplication.

_on_dup_kv

DuplicationBehavior in the event of key and value duplication.

__copy__()

Like dict.copy().

__getitem__(*args)

Like dict’s __getitem__.

__init__(*args, **kw)[source]

Like dict’s __init__.

__iter__(*args)

Like dict’s __iter__.

__len__(*args)

Like dict’s __len__.

_dedup_item(key, val, on_dup_key, on_dup_val, on_dup_kv)[source]

Check key and val for any duplication in self.

Handle any duplication as per the given duplication behaviors.

(key, val) already present is construed as a no-op, not a duplication.

If duplication is found and the corresponding duplication behavior is RAISE, raise the appropriate error.

If duplication is found and the corresponding duplication behavior is IGNORE, return None.

If duplication is found and the corresponding duplication behavior is OVERWRITE, or if no duplication is found, return the dedup result (isdupkey, isdupval, invbyval, fwdbykey).

_fwd_class

alias of dict

_inv_class

alias of dict

_update_rbf(on_dup_key, on_dup_val, on_dup_kv, *args, **kw)[source]

Update, rolling back on failure.

copy()[source]

Like dict.copy().

inv

The inverse bidict.

values() → a set-like object providing a view on B's values.

Note that because values of a BidirectionalMapping are also keys of its inverse, this returns a KeysView object rather than a ValuesView object, conferring set-like benefits.

exception bidict.BidictException[source]

Base class for bidict exceptions.

class bidict.DuplicationBehavior(id)[source]

Provide RAISE, OVERWRITE, IGNORE, and ON_DUP_VAL duplication behaviors.

RAISE

Raise an exception when a duplication is encountered.

OVERWRITE

Overwrite an existing item when a duplication is encountered.

IGNORE

Keep the existing item and ignore the new item when a duplication is encountered.

ON_DUP_VAL

Used with on_dup_kv to specify that it should match whatever the duplication behavior of on_dup_val is.

exception bidict.DuplicationError[source]

Base class for exceptions raised when uniqueness is violated.

exception bidict.KeyDuplicationError[source]

Raised when a given key is not unique.

exception bidict.ValueDuplicationError[source]

Raised when a given value is not unique.

exception bidict.KeyAndValueDuplicationError[source]

Raised when a given item’s key and value are not unique.

That is, its key duplicates that of another item, and its value duplicates that of a different other item.

class bidict.bidict(*args, **kw)[source]

Mutable bidirectional map type.

__delitem__(key)[source]

Like dict’s __delitem__.

__setitem__(key, val)[source]

Set the value for key to val.

If key is already associated with val, this is a no-op.

If key is already associated with a different value, the old value will be replaced with val, as with dict’s __setitem__.

If val is already associated with a different key, an exception is raised to protect against accidental removal of the key that’s currently associated with val.

Use put instead if you want to specify different behavior in the case that the provided key or value duplicates an existing one. Or use forceput to unconditionally associate key with val, replacing any existing items as necessary to preserve uniqueness.

Raises:
clear()[source]

Remove all items.

forceput(key, val)[source]

Associate key with val unconditionally.

Replace any existing mappings containing key key or value val as necessary to preserve uniqueness.

forceupdate(*args, **kw)[source]

Like a bulk forceput.

pop(key, *args)[source]

Like dict.pop().

popitem(*args, **kw)[source]

Like dict.popitem().

put(key, val, on_dup_key=<RAISE>, on_dup_val=<RAISE>, on_dup_kv=<ON_DUP_VAL>)[source]

Associate key with val with the specified duplication behaviors.

For example, if all given duplication behaviors are DuplicationBehavior.RAISE, then key will be associated with val if and only if key is not already associated with an existing value and val is not already associated with an existing key, otherwise an exception will be raised.

If key is already associated with val, this is a no-op.

Raises:
putall(items, on_dup_key=<RAISE>, on_dup_val=<RAISE>, on_dup_kv=<ON_DUP_VAL>)[source]

Like a bulk put.

If one of the given items causes an exception to be raised, none of the items is inserted.

setdefault(key, default=None)[source]

Like dict.setdefault().

update(*args, **kw)[source]

Like putall with default duplication behaviors.

In particular, for bidict.bidict, on_dup_key=OVERWRITE, on_dup_val=RAISE, and on_dup_kv=RAISE.

For bidict.loosebidict, on_dup_key=OVERWRITE, on_dup_val=OVERWRITE, and on_dup_kv=OVERWRITE.

class bidict.loosebidict(*args, **kw)[source]

Mutable bidict with OVERWRITE duplication behaviors by default.

class bidict.looseorderedbidict(*args, **kw)[source]

Mutable orderedbidict with OVERWRITE duplication behaviors by default.

class bidict.FrozenBidictBase(*args, **kw)[source]

Base class for frozen bidict types.

__hash__()[source]

Return the hash of this frozen bidict from its contained items.

Delegates to _compute_hash on the first call, then caches the result to make future calls O(1).

As a result, in the event that two distinct frozen bidict instances hash into the same bucket in a set or mapping, the time spent in __hash__ will generally be dominated by the time spent __eq__ (which must be called to check if a hash collision between two unequal instances has actually occurred). If they are unequal, the __eq__ call may short circuit in sublinear time, but in the worst case it will be O(n). If they are equal, the call will always be O(n). So, if inserting frozen bidicts into a set or mapping, the more items in the bidicts, the more the benefits of __hash__ distributing unequal instances into different buckets.

The result of _compute_hash is combined with the class in a final derived hash, to differentiate it from the hash of a different type of collection comprising the same items (e.g. frozenset or tuple).

_compute_hash()[source]

Abstract method to actually compute the hash.

Default implementations are provided by frozenbidict and frozenorderedbidict, with tunable behavior via _USE_ITEMSVIEW_HASH and _HASH_NITEMS_MAX, respectively.

If greater customization is needed, you can override this method in a subclass, but make sure you define __hash__ in your subclass explicitly (e.g. “__hash__ = FrozenBidictBase.__hash__”), as Python does not resolve __hash__ to a base class implementation through inheritance; it will implicitly be set to None if you don’t.

class bidict.frozenbidict(*args, **kw)[source]

Regular frozen bidict type.

_USE_ITEMSVIEW_HASH

Defaults to True on PyPy and False otherwise. Override this to change the default behavior of _compute_hash. See _compute_hash for more information.

__hash__()[source]

Delegate to FrozenBidictBase.__hash__.

_compute_hash()[source]

If _USE_ITEMSVIEW_HASH is True, use the pure Python implementation of Python’s frozenset hashing algorithm from collections.Set._hash to compute the hash incrementally in constant space.

Otherwise, create an ephemeral frozenset out of the contained items and pass it to hash(). On CPython, this results in the faster frozenset_hash routine (implemented in setobject.c) being used. CPython does not expose a way to use the fast C implementation of the algorithm without creating a frozenset.

class bidict.frozenorderedbidict(*args, **kw)[source]

Ordered frozen bidict type.

_HASH_NITEMS_MAX

The maximum number of items that participate in influencing the hash value. Defaults to None, signifying that all items participate. Override to limit the time and space complexity of _compute_hash. See _compute_hash for more information.

__hash__()[source]

Delegate to FrozenBidictBase.__hash__.

_compute_hash()[source]

Because items are ordered, this uses Python’s tuple hashing algorithm to compute a hash of the contained items.

Python does not expose a way to use its tuple hashing algorithm on an arbitrary iterable, so to use the algorithm, an ephemeral tuple from the contained items must be created and passed to hash(). i.e. The space complexity of this method is not constant. However, on CPython, this results in the tuplehash routine implemented in tupleobject.c being used, so this is faster than computing the hash incrementally in pure Python, which could be done in constant space.

Time and space complexity can be bounded by overriding _HASH_NITEMS_MAX to limit the number of items that participate in influencing the hash value. This is safe because contained items have a guaranteed ordering, so not all items need to participate in the hash to guarantee that two equal frozenorderedbidicts have the same hash value, as long as both use the same _HASH_NITEMS_MAX.

bidict.namedbidict(typename, keyname, valname, base_type=<class 'bidict._bidict.bidict'>)[source]

Create a bidict type with custom accessors.

Analagous to collections.namedtuple().

class bidict.OrderedBidictBase(*args, **kw)[source]

Base class for orderedbidict and frozenorderedbidict.

__copy__()

Like BidictBase.copy.

__iter__()

Like OrderedDict’s __iter__.

__reversed__()

Like OrderedDict’s __reversed__.

_isdupitem(key, val, nodeinv, nodefwd)[source]

Return whether (key, val) duplicates an existing item.

_should_compare_order_sensitive(mapping)[source]

Whether we should compare order-sensitively to mapping.

Returns True iff isinstance(mapping, OrderedBidictBase). Override this in a subclass to customize this behavior.

copy()[source]

Like BidictBase.copy.

class bidict.orderedbidict(*args, **kw)[source]

Mutable bidict type that maintains items in insertion order.

move_to_end(key, last=True)[source]

Like collections.OrderedDict.move_to_end().

popitem(last=True)[source]

Like collections.OrderedDict.popitem().

bidict.pairs(*args, **kw)[source]

Yield the (k, v) pairs provided, as they’d be processed if passed to dict.

If a positional argument is provided, its pairs are yielded before those of any keyword arguments. The positional argument may be a mapping or sequence or pairs.

>>> list(pairs({'a': 1}, b=2))
[('a', 1), ('b', 2)]
>>> list(pairs([('a', 1), ('b', 2)], b=3))
[('a', 1), ('b', 2), ('b', 3)]
Raises:TypeError – if more than one positional arg is given.
bidict.inverted(data)[source]

Yield the inverse items of the provided mapping or iterable.

Works with any object that can be iterated over as a mapping or in pairs, or that implements its own __inverted__ method.

bidict.util

Utilities for working with one-to-one relations.

bidict.util.inverted(data)[source]

Yield the inverse items of the provided mapping or iterable.

Works with any object that can be iterated over as a mapping or in pairs, or that implements its own __inverted__ method.

bidict.util.pairs(*args, **kw)[source]

Yield the (k, v) pairs provided, as they’d be processed if passed to dict.

If a positional argument is provided, its pairs are yielded before those of any keyword arguments. The positional argument may be a mapping or sequence or pairs.

>>> list(pairs({'a': 1}, b=2))
[('a', 1), ('b', 2)]
>>> list(pairs([('a', 1), ('b', 2)], b=3))
[('a', 1), ('b', 2), ('b', 3)]
Raises:TypeError – if more than one positional arg is given.

bidict.compat

Compatibility helpers.

bidict.compat.PY2

True iff running on Python 2.

bidict.compat.PYPY

True iff running on PyPy.

bidict.compat.viewkeys

viewkeys(D) → a set-like object providing a view on D’s keys.

bidict.compat.viewvalues

viewvalues(D) → an object providing a view on D’s values.

bidict.compat.viewitems

viewitems(D) → a set-like object providing a view on D’s items.

bidict.compat.iterkeys

iterkeys(D) → an iterator over the keys of D.

bidict.compat.itervalues

itervalues(D) → an iterator over the values of D.

bidict.compat.iteritems

iteritems(D) → an iterator over the (key, value) items of D.

bidict.compat.izip

Alias for zip() on Python 3 / itertools.izip on Python 2.