Created
July 17, 2015 06:00
-
-
Save mikofski/87a5174cc71f4b7e000e to your computer and use it in GitHub Desktop.
autovivication
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"class AutoVivication(dict):\n", | |
" \"\"\"\n", | |
" Adding new key without value creates new AutoVivication as value allowing nested dictionary creation in one line.\n", | |
" \n", | |
" >>> a = AutoVivication()\n", | |
" >>> a[1][2]['test'] = [3, 4, 5]\n", | |
" {1: {2: {'test': [3, 4, 5]}}}\n", | |
" \"\"\"\n", | |
" def __getitem__(self, key):\n", | |
" \"\"\"\n", | |
" Overide dict.__getitem__()\n", | |
" \n", | |
" If key is already in dictionary, return it. Otherwise autovivacate; i.e. create new key-value pair by calling\n", | |
" base dict.__setitem__(self, key, AutoVivication())\n", | |
" \"\"\"\n", | |
" print '\\n> inside __getitem__'\n", | |
" \n", | |
" try:\n", | |
" # try base dict.__getitem__() method\n", | |
" print '> checking if key, \"%r\", is in this AutoVivication' % key\n", | |
" return dict.__getitem__(self, key)\n", | |
" \n", | |
" except KeyError:\n", | |
" # key did not exist\n", | |
" print '> key, \"%r\", did not exist' % key\n", | |
" print '> creating new empty AutoVivication inside this current AutoVivication at key, \"%r\"' % key\n", | |
" # call base dict.__setitem__() method\n", | |
" # use introspection to refer to parent class (AutoVivication) without naming it explicitly, thus making the code\n", | |
" # more maintainable.\n", | |
" \n", | |
" self[key] = value = type(self)() # type(self)() is equivalent to self.__class__()\n", | |
" # reads from right to left\n", | |
" # >>> value = self.__class__() # create a new AutoVivication object\n", | |
" # >>> self.__setitem__(key, value) # set key-value pair\n", | |
" #\n", | |
" # __setitem__() returns None, so must cache value to return it\n", | |
" # since __setitem__() is not overridden, dict.__setitem__(self, key, value) is equivalent to\n", | |
" # self.__setitem__(key, value)\n", | |
" \n", | |
" # return new empty AutoVivication\n", | |
" print 'return new empty AutoVivcation, \"%r\"\\n' % value\n", | |
" return value" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"a = {}\n" | |
] | |
} | |
], | |
"source": [ | |
"a = AutoVivication() # new autovivcation class object\n", | |
"print 'a = %r' % a" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"\n", | |
"> inside __getitem__\n", | |
"> checking if key, \"1\", is in this AutoVivication\n", | |
"> key, \"1\", did not exist\n", | |
"> creating new empty AutoVivication inside this current AutoVivication at key, \"1\"\n", | |
"return new empty AutoVivcation, \"{}\"\n", | |
"\n", | |
"\n", | |
"> inside __getitem__\n", | |
"> checking if key, \"2\", is in this AutoVivication\n", | |
"> key, \"2\", did not exist\n", | |
"> creating new empty AutoVivication inside this current AutoVivication at key, \"2\"\n", | |
"return new empty AutoVivcation, \"{}\"\n", | |
"\n", | |
"a = {1: {2: {'foo': [5, 6, 7]}}}\n" | |
] | |
} | |
], | |
"source": [ | |
"a[1][2]['foo'] = [5, 6, 7] # autovivicate a[1] and a[1][2], then set a[1][2]['foo'] to [5, 6, 7]\n", | |
"print 'a = %r' % a" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": { | |
"collapsed": false, | |
"scrolled": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"\n", | |
"> inside __getitem__\n", | |
"> checking if key, \"1\", is in this AutoVivication\n", | |
"\n", | |
"> inside __getitem__\n", | |
"> checking if key, \"2\", is in this AutoVivication\n", | |
"a = {1: {2: {'foo': [5, 6, 7], 'bar': [0.1, 0.2, 0.3]}}}\n" | |
] | |
} | |
], | |
"source": [ | |
"a[1][2]['bar'] = [0.1, 0.2, 0.3] # autovivicates a[4] then set a[1][2]['bar'] to [0.1, 0.2, 0.3]\n", | |
"print 'a = %r' % a" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 2", | |
"language": "python", | |
"name": "python2" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 2 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython2", | |
"version": "2.7.9" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment