2012-01-03 6 views
7

मैं सबसे सरल सामान्य तरीका यह अजगर सूची कन्वर्ट करने के लिए देख रहा हूँ:जेनेरिक तरह से अजगर में फ्लैट सूची से नेस्टेड शब्दकोश बनाने के लिए

में
x = [ 
     {"foo":"A", "bar":"R", "baz":"X"}, 
     {"foo":"A", "bar":"R", "baz":"Y"}, 
     {"foo":"B", "bar":"S", "baz":"X"}, 
     {"foo":"A", "bar":"S", "baz":"Y"}, 
     {"foo":"C", "bar":"R", "baz":"Y"}, 
    ] 

:

foos = [ 
     {"foo":"A", "bars":[ 
           {"bar":"R", "bazs":[ {"baz":"X"},{"baz":"Y"} ] }, 
           {"bar":"S", "bazs":[ {"baz":"Y"} ] }, 
          ] 
     }, 
     {"foo":"B", "bars":[ 
           {"bar":"S", "bazs":[ {"baz":"X"} ] }, 
          ] 
     }, 
     {"foo":"C", "bars":[ 
           {"bar":"R", "bazs":[ {"baz":"Y"} ] }, 
          ] 
     }, 
     ] 

संयोजन "foo "," बार "," बाज़ "अद्वितीय है, और जैसा कि आप देख सकते हैं कि सूची इस कुंजी द्वारा जरूरी नहीं है।

+6

यह करने के लिए आपका (आवश्यक रूप से सबसे सरल, लेकिन आपका) तरीका क्या नहीं है? – eumiro

उत्तर

3
#!/usr/bin/env python3 
from itertools import groupby 
from pprint import pprint 

x = [ 
     {"foo":"A", "bar":"R", "baz":"X"}, 
     {"foo":"A", "bar":"R", "baz":"Y"}, 
     {"foo":"B", "bar":"S", "baz":"X"}, 
     {"foo":"A", "bar":"S", "baz":"Y"}, 
     {"foo":"C", "bar":"R", "baz":"Y"}, 
    ] 


def fun(x, l): 
    ks = ['foo', 'bar', 'baz'] 
    kn = ks[l] 
    kk = lambda i:i[kn] 
    for k,g in groupby(sorted(x, key=kk), key=kk): 
     kg = [dict((k,v) for k,v in i.items() if k!=kn) for i in g] 
     d = {} 
     d[kn] = k 
     if l<len(ks)-1: 
      d[ks[l+1]+'s'] = list(fun(kg, l+1)) 
     yield d 

pprint(list(fun(x, 0))) 

[{'bars': [{'bar': 'R', 'bazs': [{'baz': 'X'}, {'baz': 'Y'}]}, 
      {'bar': 'S', 'bazs': [{'baz': 'Y'}]}], 
    'foo': 'A'}, 
{'bars': [{'bar': 'S', 'bazs': [{'baz': 'X'}]}], 'foo': 'B'}, 
{'bars': [{'bar': 'R', 'bazs': [{'baz': 'Y'}]}], 'foo': 'C'}] 

ध्यान दें: dict अव्यवस्थित है! लेकिन यह आपके जैसा ही है।

0

मैं एक समारोह है कि इस तरह एकल समूह कदम प्रदर्शन निर्धारित करना होगा:

from itertools import groupby 
def group(items, key, subs_name): 
    return [{ 
     key: g, 
     subs_name: [dict((k, v) for k, v in s.iteritems() if k != key) 
      for s in sub] 
    } for g, sub in groupby(sorted(items, key=lambda item: item[key]), 
     lambda item: item[key])] 

और फिर

[{'foo': g['foo'], 'bars': group(g['bars'], "bar", "bazs")} for g in group(x, 
    "foo", "bars")] 

जो foos के लिए वांछित परिणाम देता है।

0

यह डेटा पर एक सरल लूप है, कोई रिकर्सन नहीं है। एक सहायक पेड़ जहां मूल्यों को कुंजीपटल के रूप में उपयोग किया जाता है, परिणामस्वरूप पेड़ के लिए इंडेक्स के रूप में उपयोग किया जाता है।

def make_tree(diclist, keylist): 
    indexroot = {} 
    root = {} 
    for d in diclist: 
     walk = indexroot 
     parent = root 
     for k in keylist: 
      walk = walk.setdefault(d[k], {}) 
      node = walk.setdefault('node', {}) 
      if not node: 
       node[k] = d[k] 
       parent.setdefault(k+'s',[]).append(node) 
      walk = walk.setdefault('children', {}) 
      parent = node 
    return root[keylist[0]+'s'] 

foos = make_tree(x, ["foo","bar","baz"]) 
संबंधित मुद्दे