Question

Underscore has a handy little function, findWhere() which can be used to find a certain structure in a list like

myList = [
  {'name': 'Thor'},
  {'name': 'Odin'},
  {'name': 'Freya'},
  {'name': 'Skadi'}
];
findWhere(myList, {'name': 'Skadi'});

result: [{'name': 'Skadi'}]

Better example:

my_list = [
   {'name': 'Thor',
    'occupation': 'God of Thunder',
    'favorite color': 'MY HAMMER'}
   {'name': 'Skadi',
   'occupation': 'Queen of the Ice Giants',
   'favorite color': 'purpz'}
  ]
findWhere(my_list, {'name': 'Skadi'})

result:

[{'name': 'Skadi',
'occupation': 'Queen of the Ice Giants',
'favorite color': 'purpz'}]

Alas, I cannot find anything similar in python. What would be a pythonic way to implement the same functionality?

Was it helpful?

Solution

You could simply define this as a generator:

def find_where(iterable, dct):
    for item in iterable:
        if all(item[key] == value for key, value in dct.items()):
            yield item

my_list = [
  {'name': 'Thor', 'age': 23},
  {'name': 'Odin', 'age': 42},
  {'name': 'Freya', 'age': 50},
  {'name': 'Skadi', 'age': 23},
]

print list(find_where(my_list, {'age': 23}))

Output:

[{'age': 23, 'name': 'Thor'}, {'age': 23, 'name': 'Skadi'}]

Also see all() and list comprehensions for details on the "meat" of the expression.

OTHER TIPS

I'd use filter with curried subset predicate:

# assuming both key and values are hashable
subset = lambda subset: (lambda superset: set(subset.items()).issubset(set(superset.items())))
results = filter(subset(needle), haystack)

alternatively, if the values of the dict may not be hashable, subset would need to be:

subset_nh = lambda subset: (lambda superset: all(item in superset.items() for item in subset.items()))
results = filter(subset_nh(needle), haystack)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top