Как отфильтровать массив объектов по вложенному атрибуту, используя лямбду и hasattr? - PullRequest
0 голосов
/ 04 марта 2019

У меня есть следующий код Python:

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)

Я ожидаю получить длину 1 на втором отпечатке, но это 0.Можете ли вы сказать мне, что не так с моим кодом?

Ответы [ 2 ]

0 голосов
/ 04 марта 2019
myArray_filtered = [v for v in myArray if v.get('specs', {}).get('color')]
print(len(myArray_filtered))

Немного проще, просто используя списочные выражения.

И вы можете добавить к условию:

myArray_filtered = [v for v in myArray if v.get('specs', {}).get('color') and v.get('specs', {}).get('width') == 2]
print(len(myArray_filtered))
0 голосов
/ 04 марта 2019

Учитывая вашу вложенную структуру, вы можете использовать dict.get с некоторыми значениями по умолчанию:

>>> 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'}}]
...