Convert (sorted) list of dics to nested list ?

Discussion in 'Python' started by shearichard@gmail.com, Mar 21, 2006.

  1. Guest

    Hi - I want to take something like ...

    lstIn = []
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 10, 'LEA_AUTOID': 1000})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 11, 'LEA_AUTOID': 2000})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 11, 'LEA_AUTOID': 2001})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 11, 'LEA_AUTOID': 2003})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3000})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3001})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3002})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3003})
    lstIn.append({'COM_AUTOID': 2, 'PRG_AUTOID': 110, 'LEA_AUTOID': 4000})


    .... and produce something like ...

    sampleOut =
    [[1,[10,1000]],[1,[11,[2000,2001,2003]]],[1,[12,[3000,3001,3002,3003]]],[2,[110,4000]]


    Well I've now been around the block a few times with this one and I'm
    still frowning !! In the process my code has become uglier and uglier -
    I'm sure there must be quite an elegant way of dealing with it - could
    anyone give me a push in the right direction ?

    Just to provide some motivation here - I should just say that this is
    cut down test case - the real problem involves creating a Javascript
    structure which in turn defines a three level menu.

    The resulting JS will be something like this, I think you can see how
    the nested loops get into it.:

    var MENU_ITEMS = [
    { pos:'relative', leveloff:[b,a], itemoff:[d,c], size:[e,f], ... },
    { ...Item 1... },
    { ...Item 2... ,
    sub:[
    { ...level format... },
    { ...Item 1... },
    { ...Item 2... },
    { ...Item 3... ,
    sub:[
    { ...level format... },
    { ...Item 1... },
    { ...Item 2... },
    { ...Item 3... },
    { ...Item 4... }
    ]
    },
    { ...Item 4... },
    ]
    },
    { ...Item 3... }
    ];

    Interested to hear of any smart/elegant ideas.

    thanks

    Richard.
    , Mar 21, 2006
    #1
    1. Advertising

  2. Larry Bates Guest

    wrote:
    > Hi - I want to take something like ...
    >
    > lstIn = []
    > lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 10, 'LEA_AUTOID': 1000})
    > lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 11, 'LEA_AUTOID': 2000})
    > lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 11, 'LEA_AUTOID': 2001})
    > lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 11, 'LEA_AUTOID': 2003})
    > lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3000})
    > lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3001})
    > lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3002})
    > lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3003})
    > lstIn.append({'COM_AUTOID': 2, 'PRG_AUTOID': 110, 'LEA_AUTOID': 4000})
    >
    >
    > ... and produce something like ...
    >
    > sampleOut =
    > [[1,[10,1000]],[1,[11,[2000,2001,2003]]],[1,[12,[3000,3001,3002,3003]]],[2,[110,4000]]
    >
    >
    > Well I've now been around the block a few times with this one and I'm
    > still frowning !! In the process my code has become uglier and uglier -
    > I'm sure there must be quite an elegant way of dealing with it - could
    > anyone give me a push in the right direction ?
    >
    > Just to provide some motivation here - I should just say that this is
    > cut down test case - the real problem involves creating a Javascript
    > structure which in turn defines a three level menu.
    >
    > The resulting JS will be something like this, I think you can see how
    > the nested loops get into it.:
    >
    > var MENU_ITEMS = [
    > { pos:'relative', leveloff:[b,a], itemoff:[d,c], size:[e,f], ... },
    > { ...Item 1... },
    > { ...Item 2... ,
    > sub:[
    > { ...level format... },
    > { ...Item 1... },
    > { ...Item 2... },
    > { ...Item 3... ,
    > sub:[
    > { ...level format... },
    > { ...Item 1... },
    > { ...Item 2... },
    > { ...Item 3... },
    > { ...Item 4... }
    > ]
    > },
    > { ...Item 4... },
    > ]
    > },
    > { ...Item 3... }
    > ];
    >
    > Interested to hear of any smart/elegant ideas.
    >
    > thanks
    >
    > Richard.
    >

    Might not be 'elegant', but at least it works.

    -Larry

    lstIn = []
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 10, 'LEA_AUTOID': 1000})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 11, 'LEA_AUTOID': 2000})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 11, 'LEA_AUTOID': 2001})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 11, 'LEA_AUTOID': 2003})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3000})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3001})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3002})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3003})
    lstIn.append({'COM_AUTOID': 2, 'PRG_AUTOID': 110, 'LEA_AUTOID': 4000})

    c="COM_AUTOID"
    p="PRG_AUTOID"
    l="LEA_AUTOID"

    lastc=None
    lastp=None

    sampleOut=[]
    for entry in lstIn:
    C=entry[c]
    P=entry[p]
    L=entry[l]
    if C != lastc or P != lastp: sampleOut.append([C,[P,L]])
    else: sampleOut[-1:][0][1].append(L)
    lastc=C
    lastp=P

    print "sampleOut=", sampleOut
    Larry Bates, Mar 21, 2006
    #2
    1. Advertising

  3. wrote:

    > Hi - I want to take something like ...
    >
    > lstIn = []
    > lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 10, 'LEA_AUTOID': 1000})
    > lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 11, 'LEA_AUTOID': 2000})
    > lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 11, 'LEA_AUTOID': 2001})
    > lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 11, 'LEA_AUTOID': 2003})
    > lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3000})
    > lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3001})
    > lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3002})
    > lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3003})
    > lstIn.append({'COM_AUTOID': 2, 'PRG_AUTOID': 110, 'LEA_AUTOID': 4000})
    >
    >
    > ... and produce something like ...
    >
    > sampleOut =
    > [[1,[10,1000]],[1,[11,[2000,2001,2003]]],[1,[12,[3000,3001,3002,3003]]],[2,[110,4000]]
    >
    >


    lstIn = []
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 10, 'LEA_AUTOID': 1000})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 11, 'LEA_AUTOID': 2000})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 11, 'LEA_AUTOID': 2001})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 11, 'LEA_AUTOID': 2003})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3000})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3001})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3002})
    lstIn.append({'COM_AUTOID': 1, 'PRG_AUTOID': 12, 'LEA_AUTOID': 3003})
    lstIn.append({'COM_AUTOID': 2, 'PRG_AUTOID': 110, 'LEA_AUTOID': 4000})

    C="COM_AUTOID"
    P="PRG_AUTOID"
    L="LEA_AUTOID"

    d = {}

    # convert data to nested dictionary structure
    for item in lstIn:
    c, p, l = item[C], item[P], item[L]
    if c not in d:
    d[c] = dict( {p : [l]} )
    else:
    if p not in d[c]:
    d[c][p] = [l]
    else:
    d[c][p].append(l)

    def dict2list( adict ):
    for key in sorted(adict.keys()):
    if isinstance( adict[key], dict ):
    for item in dict2list(adict[key]):
    yield [key] + item
    else:
    yield [[key] + [adict[key]]]

    result = list(dict2list(d))

    cigar =
    [[1,[10,1000]],[1,[11,[2000,2001,2003]]],[1,[12,[3000,3001,3002,3003]]],[2,[110,4000]]]
    no_cigar =
    [[1,[10,[1000]]],[1,[11,[2000,2001,2003]]],[1,[12,[3000,3001,3002,3003]]],[2,[110,[4000]]]]

    assert result == no_cigar

    print
    print 'nested dict: ', d
    print
    print 'result: ', result

    nested dict: {1: {10: [1000], 11: [2000, 2001, 2003], 12: [3000, 3001,
    3002, 3003]}, 2: {110: [4000]}}

    result: [[1, [10, [1000]]], [1, [11, [2000, 2001, 2003]]], [1, [12,
    [3000, 3001, 3002, 3003]]], [2, [110, [4000]]]]

    Gerard
    Gerard Flanagan, Mar 22, 2006
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andy Sutorius

    Sorted List Snapshot?

    Andy Sutorius, Jun 3, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    395
    Derek Harmon
    Jun 3, 2005
  2. =?Utf-8?B?UCBL?=

    sorted List

    =?Utf-8?B?UCBL?=, Nov 14, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    2,630
    Karl Seguin
    Nov 15, 2005
  3. POM
    Replies:
    8
    Views:
    708
    Silvio Bierman
    Jun 14, 2004
  4. Klaus Neuner
    Replies:
    7
    Views:
    486
    Klaus Neuner
    Jul 26, 2004
  5. Santiago  Romero
    Replies:
    10
    Views:
    529
    Peter Otten
    Jan 21, 2008
Loading...

Share This Page