Search code examples
pythonarraysobjectlambdahasattr

How to filter an array of objects on nested attribute using lambda and hasattr?


I have the following Python code:

myArray = [{ "id": 1, "desc": "foo", "specs": { "width": 1, "height": 1}}, { "id": 2, "desc": "bar", "specs": { "width": 2, "height": 2, "color": "black"}}, { "id": 3, "desc": "foobar"}]
print len(myArray)

myArray_filtered = filter(lambda item : hasattr(item, "specs") and hasattr(item.specs, "color"), myArray)
print len(myArray_filtered)

I expect to get length 1 on second print, but it is 0. Can you tell me what's wrong with my code?


Solution

  • Given your nested structure, you could use dict.get with some default values:

    >>> myArray_filtered = list(filter(lambda d: d.get("specs", {}).get("color") is not None, myArray))
    >>> len(myArray_filtered)
    1
    >>> myArray_filtered
    [{'id': 2, 'desc': 'bar', 'specs': {'width': 2, 'height': 2, 'color': 'black'}}]