DeChinees
DeChinees

Reputation: 293

Get to nested dictionary in list

I'm struggling to get to a nested dictionary in a list.

L = [{'color':'yellow','fruit':'banana'},{'firstname':'Jack','lastname':'Black'}]

I can get the individual dictionaries with the following code.

for a in L:
   print (a)

{'color': 'yellow', 'fruit': 'banana'}
{'lastname': 'Black', 'firstname': 'Jack'}

But now I only want the dictionary with lastname/firstname.

After the tips posted to my question, I came up with the following code.

def getPhotosFromAlbum(albumName):
    availablePhotos = []
    availableAlbums = getAlbumList()
    print("Looking in album %s" %albumName)
    for album in availableAlbums:
        if albumName == album['AlbumName']:
            #print ("found photos for album: ", albumName['KeyList'])
            for photoRefKey in album['KeyList']:
                print(getPhotoPath(photoRefKey))
                availablePhotos.append(getPhotoPath(photoRefKey))
    return availablePhotos 

The idea behind this function is that I can parse the list in a HTML template file to display the photos. So my follow up question is: is this code ok or is there a more Python like approach to achieve the same result.

Darrell.

Upvotes: 0

Views: 82

Answers (2)

kiriloff
kiriloff

Reputation: 26333

I build on Martijn's answer to propose a solution:

  • returning a print of items, just like in your example (and not a list)
  • checking that keys are exactly 'lastname' and 'firstname' (not just contain)

script uses an helper to check very simply if one list is sublist of another

L = [{'color':'yellow','fruit':'banana'},{'firstname':'Jack','lastname':'Black'}]

def contains_sublist(lst, sublst):
    for k in sublst:
        if k not in lst:
            return False
    return True

for di in L:
    if len(di.keys()) == 2 and contains_sublist(di.keys(),
                                                       ['firstname','lastname']):
        print di

returns

>>> 
{'lastname': 'Black', 'firstname': 'Jack'}

////////// EDIT -- thanks Martijn

You can use .viewkeys() for increased efficiency

L = [{'color':'yellow','fruit':'banana'},{'firstname':'Jack','lastname':'Black'}]

for di in L:
    if len(di) == 2 and di.viewkeys() & {'firstname','lastname'}:
        print di

this one checks if intersection between both sets is non empty di.viewkeys() & {'firstname','lastname'}

Upvotes: 1

Martijn Pieters
Martijn Pieters

Reputation: 1124778

Use a list comprehension:

only_last_and_first = [d for d in L if 'firstname' in d and 'lastname' in d]

Now you have a list of dictionaries that have those two keys.

Demo:

>>> L = [{'color':'yellow','fruit':'banana'},{'firstname':'Jack','lastname':'Black'}]
>>> [d for d in L if 'firstname' in d and 'lastname' in d]
[{'lastname': 'Black', 'firstname': 'Jack'}]

If you only wanted the first such a dictionary, use next() and a generator expression:

first = next((d for d in L if 'firstname' in d and 'lastname' in d), None)

Here first will be set to either the first dictionary with the two keys, or None if there is no such dictionary.

If such syntax is a little daunting, here is a version with a for loop instead:

first = None
for d in L:
    if 'firstname' in d and 'lastname' in d:
        first = d
        break

Upvotes: 1

Related Questions