Giter Club home page Giter Club logo

dictregister's Introduction

DictRegister

Build Status Version PyPi Downloads

Documentation

dictregister documentation

dictregister provides an object that contains an ordered list of dictionaries with some functions to search and manage them.

Dictionaries are useful objects, as they can easily represent complex objects; being a basic language structure in Python they are very handy: as an instance, they are serialiable, and if you ever worked with JSON you are accustomed to see them around.

When dealing with more than one dictionary, namely a list of them, a problem arises: searching the list for dictionaries is complex and you usually write a bunch of repeated code to get the information you need.

dictregister acts as a standard Python list but can contain only dictionaries (actually objects implementing collections.Mapping); additionally, it provides functions to search and manage dictionaries by key, to manage single keys and to store more than one value for each key.

dictregister is a pure Python package, but its syntax has been heavily influenced by Django's query syntax, so Django users will find at home.

Indeed, dictregister acts like a small key/value database. Please note that there it stores values in memory and there is no optimization, so use it for small collections.

Basic usage

The DictRegister object acts as a list, so you can either initialize it empty

import dictregister
dr = dictregister.DictRegister()

or with an iterable object as an argument

import dictregister
dr = dictregister.DictRegister([{'x':1, 'y':2}, {'x':3, 'y':4}])

and you can use any method of list like append()

import dictregister
dr = dictregister.DictRegister()
dr.append({'x':1, 'y':2})

DictRegister accepts only objects that inherit from the collections.Mapping Abstract Base Class. If you try to insert an object that does not stick with this rule you will receive a TypeError.

Managing keys

You can manage keys in batch mode with kadd(), kreplace(), and kremove().

Adding a key to each element is easy with kadd()

import dictregister
dr = dictregister.DictRegister([{'x':1, 'y':2}, {'x':3, 'y':4}])
dr == [{'x':1, 'y':2}, {'x':3, 'y':4}]
dr.kadd('z', 5)
dr == [{'x':1, 'y':2, 'z':5}, {'x':3, 'y':4, 'z':5}]

Please note that if you add more than a value to the same key you get a multiple-value element, which is treated in a special way. See the Multiple values section below.

When you remove keys you can do it unconditionally

import dictregister
dr = dictregister.DictRegister([{'x':1, 'y':2}, {'x':3, 'y':4}])
dr == [{'x':1, 'y':2}, {'x':3, 'y':4}]
dr.kremove('y')
dr == [{'x':1}, {'x':3}]

which removes all keys with that name. or you can specify a value, in which case only the elments that match both the key and the value will be removed.

import dictregister
dr = dictregister.DictRegister([{'x':1, 'y':2}, {'x':3, 'y':4}])
dr == [{'x':1, 'y':2}, {'x':3, 'y':4}]
dr.kremove('y',4)
dr == [{'x':1, 'y':2}, {'x':3}]

Last, you can replace the value of a key

import dictregister
dr = dictregister.DictRegister([{'x':1, 'y':2}, {'x':3, 'y':4}])
dr == [{'x':1, 'y':2}, {'x':3, 'y':4}]
dr.kreplace('x',6)
dr == [{'x':6, 'y':2}, {'x':6, 'y':4}]

Advanced usage

You can find a subset of dictionaries using dfilter()

import dictregister
dr = dictregister.DictRegister([{'x':1, 'y':2}, {'x':3, 'y':4}])
filtdr = dr.dfilter(x=1)
filtdr == [{'x':1, 'y':2}]

You can pass as many conditions as you want to dfilter()

import dictregister
dr = dictregister.DictRegister([{'x':1, 'y':2}, {'x':3, 'y':4}, {'x':1, 'y':6}])
filtdr = dr.dfilter(x=1)
filtdr == [{'x':1, 'y':2}, {'x':1, 'y':6}]
filtdr = dr.dfilter(x=1, y=2)
filtdr == [{'x':1, 'y':2}]

You can easily get only the first element of the filtering with dget(). Remember that while dfilter() silently accepts a search that returns no values, returning an empty DictRegister, dget() raises an IndexError exception.

You can remove elements from a DictRegister object with dremove(), which returns a DictRegister containing the removed elements.

import dictregister
dr = dictregister.DictRegister([{'x':1, 'y':2}, {'x':3, 'y':4}, {'x':1, 'y':6}])
filtdr = dr.dremove(x=1)
dr == [{'x':3, 'y':4}]
filtdr == [{'x':1, 'y':2}, {'x':1, 'y':6}]

Otherwise you obtain a new object with the elements removed dremove_copy()

import dictregister
dr = dictregister.DictRegister([{'x':1, 'y':2}, {'x':3, 'y':4}, {'x':1, 'y':6}])
filtdr = dr.dremove_copy(x=1)
dr == [{'x':1, 'y':2}, {'x':3, 'y':4}, {'x':1, 'y':6}]
filtdr == [{'x':3, 'y':4}]

Last you can pop an element with dpop(), which returns the first element matching the given conditions. Remember that dpop() raises IndexError if no matching element is found.

import dictregister
dr = dictregister.DictRegister([{'x':1, 'y':2}, {'x':3, 'y':4}, {'x':1, 'y':6}])
filtdr = dr.dpop(x=1)
dr == [{'x':3, 'y':4}, {'x':1, 'y':6}]

Remember that, being a list, DictRegister also provides you a pop([i]) method that pops the element at index i or the first element if i is not specified.

Note that dfilter(), dremove(), and dremove_copy() return a DictRegister so you can easily chain calls.

import dictregister
dr = dictregister.DictRegister([{'x':1, 'y':2}, {'x':3, 'y':4}, {'x':1, 'y':6}])
filtdr = dr.dfilter(x=1).dremove_copy(y=2)
dr == [{'x':1, 'y':2}, {'x':3, 'y':4}, {'x':1, 'y':6}]
filtdr == [{'x':1, 'y':6}]

Matching elements

When using the advanced features of DictRegister like filtering you can use a special syntax for keys, namely a key__operator syntax.

The implicit operator is eq, which matches all dictionaries with the given key with the given value.

import dictregister
dr = dictregister.DictRegister([{'x':1, 'y':2}, {'x':3, 'y':4}, {'x':1, 'y':6}])
filtdr = dr.dfilter(x__eq=3)
filtdr == [{'x':3, 'y':4}]
filtdr = dr.dfilter(x=3)
filtdr == [{'x':3, 'y':4}]

The inequality can be matched with ne

import dictregister
dr = dictregister.DictRegister([{'x':1, 'y':2}, {'x':3, 'y':4}, {'x':1, 'y':6}])
filtdr = dr.dfilter(x__ne=1)
filtdr == [{'x':3, 'y':4}]

You can match dictionaries that contain or not a given key

import dictregister
dr = dictregister.DictRegister([{'x':1, 'y':2}, {'x':3, 'y':4}, {'x':1, 'y':6, 'z':8}])
filtdr = dr.dfilter(z__iskey=True)
filtdr == [{'x':1, 'y':6, 'z':8}]
filtdr = dr.dfilter(z__iskey=False)
filtdr == [{'x':1, 'y':2}, {'x':3, 'y':4}]

Multiple values

The DictRegister object can contain any dictionary with a single value for each key, like

import dictregister
dr = dictregister.DictRegister()
dr.append({'x':1, 'y':2})

If you store more than a value for a key, DictRegister uses a set to host the values. You are free to append dictionaries with generic sequences, most notably lists and sets, as values. However remeber that DictRegister does not consider the sequence itself as the value of the key, but the contained elements; so if you need to store a sequence as a value you have to store a set that contains the sequence.

import dictregister
dr = dictregister.DictRegister([{'x':1, 'y':2}, {'x':3, 'y':4}])
dr == [{'x':1, 'y':2}, {'x':3, 'y':4}]
dr.kadd('x', 2)
dr == [{'x':set([1, 2]), 'y':2}, {'x':set([2, 3]), 'y':4}]

You can match multiple values with the in and nin operators. The first matches all dictionaries that contain the given key with the given value among its values, while nin performs the opposite match.

import dictregister
dr = dictregister.DictRegister([{'x':set([1, 2]), 'y':2}, {'x':2, 'y':4}])
filtdr = dr.dfilter(x__in=2)
filtdr == [{'x':set([1, 2]), 'y':2}, {'x':2, 'y':4}]

As you can see DictRegister treats keys with a single value and with multiple values in the same way.

Installation

pip install dictregister

Contributions

Any form of contribution is warmly welcomed. Feel free to submit issues of to make changes and submit a pull request. being the first Python package I ship with all the bells and whistles like distutils, tests and friends, I gladly accept suggestions or corrections on this topic.

Thanks

Many thanks to Jeff Knupp for his post Open Sourcing a Python Project the Right Way.

Many thanks to Audrey M. Roy for her cookiecutter and cookiecutter-pypackage tools, which heavily simplified the implementation of the whole thing.

dictregister's People

Contributors

joshgeller avatar lgiordani avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

msabramo

dictregister's Issues

import dictregister doesn't get you to DictRegister class

import dictregister
dir(dictregister)
['author', 'builtins', 'doc', 'email', 'file', 'name', 'package', 'path', 'version', 'dictregister']
import dictregister.dictregister
dir(dictregister.dictregister)
['DictRegister', 'builtins', 'doc', 'file', 'name', 'package', 'collections', 'six']

So if I try to use dictregister per the documentation, I get an error:

import dictregister
d = dictregister.DictRegister()
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'module' object has no attribute 'DictRegister'

As you can see, DictRegister is buried one level down. Perhaps the init.py file needs to do something to expose the dictregister.py file as part of the module?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.