Split a key that is a string of numbers into single digit keys in Python

I would like to turn the following dictionary:

dictionary = {
    4388464: ['getting']
    827862 : ['Taruma', 'Varuna']
    ...
}

into:

dictionary = {
    4: {3: {8: {8: {4: {6: {4: {'words': ['getting']}}}}}}}
    8: {2: {7: {8: {6: {2: {'words': ['Taruma', 'Varuna']}}}}}}
    ...
}

This will then allow me to use the dictionary like: dictionary[8][2][7][8][6][2]['words'] instead of: dictionary[827862].

Answers


import pprint

dictionary = {
    4388464: ['getting'],
    43881: ['got'],
    827862 : ['Taruma', 'Varuna'],
}

d2 = {}

def add_it(d, k, words):
    knum = int(k[0])
    if len(k) == 1:
        d[knum] = {'words': words}
    else:
        dsub = d.setdefault(knum, {})
        add_it(dsub, k[1:], words)

for k, words in dictionary.items():
    add_it(d2, list(str(k)), words)


pprint.pprint(d2)

prints:

{4: {3: {8: {8: {1: {'words': ['got']},
                 4: {6: {4: {'words': ['getting']}}}}}}},
 8: {2: {7: {8: {6: {2: {'words': ['Taruma', 'Varuna']}}}}}}}

A short solution to produce the dictionaries:

def num2dict( n, d ):
  if n < 10:
    return { n: d }
  else:
    q, r = divmod( n, 10 )
    return num2dict( q, { r: d } )

print( num2dict( 4388464, { 'words': [ 'getting' ] } ) )

You could try using a recursive defaultdict:

from collections import defaultdict

# define a hierarchical defaultdict (of defaultdicts (of defaultdicts...))
class recursivedefaultdict(defaultdict):
    def __init__(self):
        self.default_factory = type(self)

# add an iterator recursively to create entries, sub-entries, etc.
def addToTree(it, v, accum):
    try:
        addToTree(it, v, accum[it.next()])
    except StopIteration:
        accum["words"] = v

# test it out
dictionary = { 
    4388464: ['getting'], 
    43881: ['got'], 
    827862 : ['Taruma', 'Varuna'], 
} 

d2 = recursivedefaultdict()
for k,v in dictionary.iteritems():
    addToTree(iter(str(k)), v, d2)


# use recursion again to view the results
def dumpDict(d,indent=""):
    for k,v in d.iteritems():
        if k == "words":
            print "%s- %s : %s" % (indent, k, v)
        else:
            print "%s- %s:" % (indent, k)
            dumpDict(v, indent+"  ")

dumpDict(d2)

Gives:

- 8:
  - 2:
    - 7:
      - 8:
        - 6:
          - 2:
            - words : ['Taruma', 'Varuna']
- 4:
  - 3:
    - 8:
      - 8:
        - 1:
          - words : ['got']
        - 4:
          - 6:
            - 4:
              - words : ['getting']

I think a recursive defaultdict is a beautiful way to create these nested dicts of unpredictable length. (Note that there will be trouble though, if the next value we add uses 43884 as the key, as there already exists an entry for d2[4][3][8][8][4].)


Need Your Help

Page Curling effect in android

android page-curl

How to implement page curling effect in android on views which have dynamic data?

VBA Dragging down formulas (in multiple rows) to last row used

vba excel-vba excel-2007 excel

I have formulas from columns O -> X and need them drag them to last row used. Below is the current code I am using: