Можно ли вложить всю функцию?
У меня есть список объектов с именем items . Каждый объект имеет состояние свойства и дочерние объекты, которые являются еще одним списком объектов. И каждый дочерний объект имеет также свойство с именем state . Я хочу знать, что каждый элемент и их дети находятся в государствах счастливыми или веселыми .
Я сделал это со всеми (анализируя состояния предметов):
if all(item.state in ['happy', 'cheerful'] for item in items): pass
Я хотел бы знать, какой лучший способ сделать то же самое не только с элементами, но и с детьми.
- Ошибка Pytube: AttributeError: объект 'module' не имеет атрибута 'Client'
- Хешировать экземпляр класса нового стиля python?
- Разница между использованием двойной кавычки и кавычками в python
- Как определить функцию, которая будет проверять, имеет ли строка пробелы после завершения предложения?
- Внутренние классы: как я могу получить объект внешнего класса во время построения?
Вы ищете рекурсию здесь:
def is_happy(items): return all(item.state in ['happy', 'cheerful'] for item in items) and all(is_happy(item.childs) for item in items)
Как отметил @tobias_k, это должно быть быстрее, так как он повторяется только один раз на элементах:
def is_happy(items): return all(item.state in ['happy', 'cheerful'] and is_happy(item.childs) for item in items)
Это, по крайней мере, более читаемо.
В случае, если у вас есть только два слоя объектов, просто для этого тоже может быть трюк.
def is_happy(items): happy_children = True for item in items: if any(child.state not in ['happy', 'cheerful'] for child in item): happy_children = False break return all(item.state in ['happy', 'cheerful'] for item in items) and happy_children
Я думаю, это было бы правильно:
if all(item.state in ['happy', 'cheerful'] and all(c.state in ['happy', 'cheerful'] for c in item.childs) for item in items): pass
Первый шаг: сгладить список предметов:
def flatten(items): for item in items: yield item for child in getattr(item, 'children', ()): yield child
Или используя Python 3.4+:
def flatten(items): for item in items: yield item yield from getattr(item, 'children', ())
И теперь вы можете выполнять итерацию через сплющенные элементы, используя all(..)
или как-то иначе:
is_happy = lambda item: getattr(item, 'state') in ('happy', 'cheerful') are_happy = lambda items: all(map(is_happy, flatten(items)))
Рекурсия – ваш друг здесь
def happy(x): return (x.state in ('happy', 'cheerful') and all(happy(xc) for xc in x.children))
Это, вероятно, лучше всего сделать вручную.
def valid(item): return item.state in ['happy', 'cheerful'] for item in items: if not (valid(item) and all(valid(child) for child in item)): break else: # success
Изменение выражения генератора для работы с этим возможно, но делает его немного взломанным.
if all(child.state in ['happy', 'cheerful'] for item in items for child in item+[item]): pass
Поэтому, чтобы ответить на ваш вопрос, да, возможно, он может вложить all
функции, и именно так вы можете это сделать, если хотите.
- Директива `uwsgi_modifier1 30` не удаляет SCRIPT_NAME из PATH_INFO как документально
- Так как пример в документации нарушен, как я могу решить нелинейную систему уравнений численно в SymPy?
- Получить последний ответ
- Подписанные URL-адреса Google Cloud Storage с Google App Engine
- GAE напишите мне ошибки
- Определение языка
- Динамическое изменение размера метки киви (и кнопки) на стороне питона
- Проблема со списком копий Python
- Создание класса для уже работающей программы в Python
- Как сделать обработчики автоматически .decode ('utf-8') для всех маршрутизируемых параметров?
- как очистить html, сгенерированный javascript, используя python?