#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    6
    Rep Power
    0

    Dictionaries containing list that contain dictionaries


    Please bear with me if I am not able to explain this clearly. I'm new to python programming although I've done some programming in perl previously. I'm kind of stuck trying to figure out how to extract some data from the following structure.


    abc = {
    7777 : [ {"name":"ark"}, { "city":"palo alto"},{ "tel":"123456789"} ],
    8888 : [ {"name": "pinky"}, {"city":"palo alto"}, {"tel" : "987654321"} ],
    9999 : [ {"name": "joey"}, {"city":"los altos"}, {"tel" : "234543213"} ],
    ...
    }


    How can I pull the value for the "tel" key inside the lists above where the "city" matches "palo alto"? I can print the lists and even indices of the lists using some for loops but I'm having a difficult time figuring out how to extract or match the 'city' in an if statement.

    Thanks!
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2012
    Posts
    83
    Rep Power
    39
    Do you have some control over the structure? Your problem would be much easier to solve if you had a dictionary of dictionaries, rather than a dictionary of lists of dictionaries, and there doesn't really seem to be any reason why you'd need a list of single-entry dictionaries rather than a dictionary with multiple entries.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    6
    Rep Power
    0
    Originally Posted by sepp2k1
    Do you have some control over the structure? Your problem would be much easier to solve if you had a dictionary of dictionaries, rather than a dictionary of lists of dictionaries, and there doesn't really seem to be any reason why you'd need a list of single-entry dictionaries rather than a dictionary with multiple entries.
    Thanks for the quick reply!

    I do have control over how the structure is built and can change it although I may need some advice for that.
    The above example I provided in the OP was contrived from my actual data to make the question a bit more clear. But here is actually what I am doing. I'm actually pulling the data from a web service call using suds. The call returns the following structure which I cannot alter.

    [(mergedDefectDataObj){
    checkerName = "NULL_RETURNS"
    checkerSubcategory = "unimpl"
    cid = 49473
    componentName = "Default.Other"
    defectStateAttributeValues[] =
    (defectStateAttributeValueDataObj){
    attributeDefinitionId =
    (attributeDefinitionIdDataObj){
    name = "Provenance"
    }
    attributeValueId =
    (attributeValueIdDataObj){
    name = "Parent - Baseline"
    }
    },
    (defectStateAttributeValueDataObj){
    attributeDefinitionId =
    (attributeDefinitionIdDataObj){
    name = "DefectStatus"
    }
    attributeValueId =
    (attributeValueIdDataObj){
    name = "New"
    }
    },
    (defectStateAttributeValueDataObj){
    attributeDefinitionId =
    (attributeDefinitionIdDataObj){
    name = "Classification"
    }
    attributeValueId =
    (attributeValueIdDataObj){
    name = "Unclassified"
    }
    },

    domain = "STATIC_C"
    filePathname = "/media/3TB/arkster/work/install/Build/gtk_Val/gtk+-2.14.2/gtk/gtkfilechooserbutton.c"

    },

    (mergedDefectDataObj){
    checkerName = "NULL_RETURNS"
    checkerSubcategory = "unimpl"
    cid = 38796
    componentName = "Default.Other"
    defectStateAttributeValues[] =
    (defectStateAttributeValueDataObj){
    attributeDefinitionId =
    (attributeDefinitionIdDataObj){
    name = "Provenance"
    }
    attributeValueId =
    (attributeValueIdDataObj){
    name = "Parent - Baseline"
    }
    },
    (defectStateAttributeValueDataObj){
    attributeDefinitionId =
    (attributeDefinitionIdDataObj){
    name = "DefectStatus"
    }
    attributeValueId =
    (attributeValueIdDataObj){
    name = "New"
    }
    },
    (defectStateAttributeValueDataObj){
    attributeDefinitionId =
    (attributeDefinitionIdDataObj){
    name = "Classification"
    }
    attributeValueId =
    (attributeValueIdDataObj){
    name = "Unclassified"
    }
    },

    domain = "STATIC_C"
    filePathname = "/media/3TB/arkster/work/install/Build/gtk_Val/gtk+-2.14.2/modules/printbackends/lpr/gtkprintbackendlpr.c"

    },
    ...
    ]

    The above is the output for self.getMergedDefectsForStreamsResponse.mergedDefects which I then process into individual dictionaries that are appended into a list using setdefault with the 'cid' being the main dictionary key. Here is the code that does that.

    for mergedDefect in self.getMergedDefectsForStreamsResponse.mergedDefects:

    for i in mergedDefect.defectStateAttributeValues:
    if i.attributeValueId == '':
    continue
    self.mergedDefectDict.setdefault(mergedDefect.cid, []).append({i.attributeDefinitionId['name']:i.attributeValueId['name']})

    self.mergedDefectDict.setdefault(mergedDefect.cid, []).append({ "componentName" : mergedDefect.componentName})
    self.mergedDefectDict.setdefault(mergedDefect.cid, []).append({ 'checkerName' :mergedDefect.checkerName})
    self.mergedDefectDict.setdefault(mergedDefect.cid, []).append({ 'domain' : mergedDefect.domain})
    self.mergedDefectDict.setdefault(mergedDefect.cid, []).append({ 'filePathName' : mergedDefect.filePathname})


    The above then creates the structure that I end up with.

    Dict = {
    49473L: [
    {Provenance: Parent - Baseline},
    {DefectStatus: New},
    {Classification: Unclassified},
    {Comment: "Please Fix." },
    {'componentName': Default.Other},
    {'checkerName': NULL_RETURNS},
    {'domain': STATIC_C},
    {'filePathName': /media/3TB/arkster/work/install/Build/gtk_Val/gtk+-2.14.2/gtk/gtkfilechooserbutton.c}
    ],


    38796L: [
    {Provenance: Parent - Baseline},
    {DefectStatus: New},
    {Classification: Unclassified},
    {Comment: "False Positive. Please ignore"},
    {'componentName': Default.Other},
    {'checkerName': NULL_RETURNS},
    {'domain': STATIC_C},
    {'filePathName': /media/3TB/arkster/work/install/Build/gtk_Val/gtk+-2.14.2/modules/printbackends/lpr/gtkprintbackendlpr.c}
    ],
    ...
    }


    Is there a way that I can manage the above using a dictionary of dictionaries instead of using setdefault to pile stuff into a list?
    I can provide more context if needed. Thanks much for the help!
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    Without knowing what these methods do, I'll guess the following might give a dictionary of dictionaries.
    Code:
    for mergedDefect in self.getMergedDefectsForStreamsResponse.mergedDefects:
        for i in mergedDefect.defectStateAttributeValues:
            if i.attributeValueId:
                d = {i.attributeDefinitionId['name']:i.attributeValueId['name'],
                     'componentName' : mergedDefect.componentName,
                     'checkerName' :mergedDefect.checkerName,
                     'domain' : mergedDefect.domain,
                     'filePathName' : mergedDefect.filePathname,
                     }
                self.mergedDefectDict.setdefault(mergedDefect.cid, {}).update(d)
    might give a dictionary with access
    Code:
    abc = { 
        7777 :  {"name":"ark", "city":"palo alto", "tel":"123456789"},
        8888 :  {"name": "pinky", "city":"palo alto", "tel" : "987654321"},
        9999 :  {"name": "joey", "city":"los altos", "tel" : "234543213"},
    }
    
    for (k,v,) in abc.items():  # if k not used, for v in abc.values():
        if v['city'] == 'palo alto':
            print(v['tel'])
    [code]Code tags[/code] are essential for python code and Makefiles!
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    6
    Rep Power
    0
    Originally Posted by b49P23TIvg
    Without knowing what these methods do, I'll guess the following might give a dictionary of dictionaries.
    Code:
    for mergedDefect in self.getMergedDefectsForStreamsResponse.mergedDefects:
        for i in mergedDefect.defectStateAttributeValues:
            if i.attributeValueId:
                d = {i.attributeDefinitionId['name']:i.attributeValueId['name'],
                     'componentName' : mergedDefect.componentName,
                     'checkerName' :mergedDefect.checkerName,
                     'domain' : mergedDefect.domain,
                     'filePathName' : mergedDefect.filePathname,
                     }
                self.mergedDefectDict.setdefault(mergedDefect.cid, {}).update(d)
    might give a dictionary with access
    Code:
    abc = { 
        7777 :  {"name":"ark", "city":"palo alto", "tel":"123456789"},
        8888 :  {"name": "pinky", "city":"palo alto", "tel" : "987654321"},
        9999 :  {"name": "joey", "city":"los altos", "tel" : "234543213"},
    }
    
    for (k,v,) in abc.items():  # if k not used, for v in abc.values():
        if v['city'] == 'palo alto':
            print(v['tel'])
    Thank you! This is just what I needed.

IMN logo majestic logo threadwatch logo seochat tools logo