我有一个名为 items 的对象列表。每个对象都有一个属性 state 和一个属性 children ,这是另一个对象列表。每个子对象还有一个名为 state 的属性。我想知道的是,每件物品及其子女是否处于快乐或欢快的状态。
我和所有人一起做过(仅分析项目的状态):
if all(item.state in ['happy', 'cheerful'] for item in items):
pass
我想知道哪种方法不仅可以用于物品,也可以用于儿童。
答案 0 :(得分:5)
你正在寻求一些递归:
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
答案 1 :(得分:2)
我想这是正确的方法:
if all(item.state in ['happy', 'cheerful'] and all(c.state in ['happy', 'cheerful'] for c in item.childs) for item in items):
pass
答案 2 :(得分:1)
第一步:展平项目清单:
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)))
答案 3 :(得分:1)
递归是你的朋友
def happy(x):
return (x.state in ('happy', 'cheerful') and
all(happy(xc) for xc in x.children))
答案 4 :(得分:1)
这可能最好手动完成。
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
更改生成器表达式以使用它是可能的,但会使它有点hacky。
if all(child.state in ['happy', 'cheerful'] for item in items for child in item+[item]):
pass
所以回答你的问题,是的,可以嵌套all
函数,如果你真的想要的话,你可以这样做。