开发者

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

开发者 https://www.devze.com 2023-01-02 12:30 出处:网络
I would like to turn the following dictionary: dictionary = { 4388464: [\'getting\'] 827862 : [\'Taruma\', \'Varu开发者_StackOverflow中文版na\']

I would like to turn the following dictionary:

dictionary = {
    4388464: ['getting']
    827862 : ['Taruma', 'Varu开发者_StackOverflow中文版na']
    ...
}

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].


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].)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号