Skip to main content

Ordered dictionary.

Project description

odict

Dictionary in which the insertion order of items is preserved (using an internal double linked list). In this implementation replacing an existing item keeps it at its original position.

Internal representation: values of the dict:

[pred_key, val, succ_key]

The sequence of elements uses as a double linked list. The links are dict keys. self.lh and self.lt are the keys of first and last element inseted in the odict. In a C reimplementation of this data structure, things can be simplified (and speed up) a lot if given a value you can at the same time find its key. With that, you can use normal C pointers.

Memory used (Python 2.5)

  • set(int): 28.2 bytes/element

  • dict(int:None): 36.2 bytes/element

  • odict(int:None): 102 bytes/element

Performance

When running the benchmark script, you get results similar to the one below on recent common hardware.

Adding and deleting dict objects.

Add 1000

0.000653028488159

Delete 1000

0.000339031219482

Add 10000

0.00774908065796

Delete 10000

0.00406503677368

Add 100000

0.130412101746

Delete 100000

0.0517508983612

Add 1000000

3.17614817619

Delete 1000000

0.564585924149

Adding and deleting odict objects.

Add 1000

0.0096800327301

Delete 1000

0.00276303291321

Add 10000

0.107849836349

Delete 10000

0.0282921791077

Add 100000

1.05564808846

Delete 100000

0.297379016876

Add 1000000

16.451695919

Delete 1000000

3.03641605377

Relation dict:odict of creating and deleting.

creating 1000 objects

1:14.823

deleting 1000 objects

1:8.1497

creating 10000 objects

1:13.917

deleting 10000 objects

1:6.9598

creating 100000 objects

1:8.0947

deleting 100000 objects

1:5.7463

creating 1000000 objects

1:5.1797

deleting 1000000 objects

1:5.3781

Usage

Import and create ordered dictionary.

>>> from odict import odict
>>> od = odict()

type conversion to ordinary dict. This will fail.

>>> dict(odict([(1, 1)]))
{1: [nil, 1, nil]}

The reason for this is here -> http://bugs.python.org/issue1615701

The __init__ function of dict checks wether arg is subclass of dict, and ignores overwritten __getitem__ & co if so.

This was fixed and later reverted due to behavioural problems with pickle.

Use one of the following ways for type conversion.

>>> dict(odict([(1, 1)]).items())
{1: 1}

>>> odict([(1, 1)]).as_dict()
{1: 1}

It is possible to use abstract mixin class _odict to hook another dict base implementation. This is useful i.e. when persisting to ZODB. Inheriting from dict and Persistent at the same time fails.

>>> from persistent.dict import PersistentDict
>>> class podict(_odict, PersistentDict):
...     def _dict_impl(self):
...         return PersistentDict

Requires

  • Python 2.4+

Changes

Version 1.4.1

  • Fix release, README.rst was missing, added MANIFEST.in file to include it jensens - 2010-11-29

Version 1.4.0

  • Full test coverage chaoflow, rnix, 2010-08-17

  • Code cleanup and optimizing chaoflow, rnix, 2010-08-17

Version 1.3.2

  • Access dict API providing class via function _dict_impl() and provide odict logic as abstract base class _odict. rnix, 2010-07-08

Version 1.3.1

  • Add test for bool evaluation rnix, 2010-04-21

Version 1.3.0

  • Fix access to odict.lt and odict.lh properties. Now it’s possible to overwrite __setattr__ and __getattr__ on odict subclass without hassle. rnix, 2010-04-06

  • Add sort function to odict. rnix, 2010-03-03

Version 1.2.6

  • Make odict serialize and deserialize properly gogo, 2010-01-12

Version 1.2.5

  • Add as_dict function. Supports type conversion to ordinary dict. rnix, 2009-12-19

  • Add benchmark script rnix, 2009-12-19

Version 1.2.4

  • Do not check for key in self on __delitem__, KeyError is raised properly anyway. Huge Speedup! rnix, jensens, 2009-12-18

Version 1.2.3

  • Move tests to seperate file and make egg testable with python setup.py test. rnix, 2009-12-07

  • improve lt and lh properties to make odict work with copy.deepcopy. rnix, 2009-12-07

Version 1.2.2

  • Use try/except instead of __iter__ in __setitem__ to determine if value was already set. rnix, 2009-07-17

Version 1.2.1

  • Add missing __len__ and __contains__ functions. rnix, 2009-03-17

Version 1.2.0

  • eggified rnix, 2009-03-17

Version < 1.2

Contributors

under the Python Software Foundation License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

odict-1.4.1.tar.gz (7.2 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page