Python 是否可以嵌套all函数?

Python 是否可以嵌套all函数?,python,Python,我有一个名为items的对象列表。每个对象都有一个属性状态和一个属性子对象,这是另一个对象列表。每个子对象也有一个名为state的属性。我想知道的是,每个项目和他们的孩子在美国是快乐还是快乐 我对所有项目都这样做了(仅分析项目的状态): 我想知道哪种方法不仅对项目,而且对子项都是最好的方法。您在这里寻找一些递归: def is_happy(items): return all(item.state in ['happy', 'cheerful'] for item in items) an

我有一个名为items的对象列表。每个对象都有一个属性状态和一个属性子对象,这是另一个对象列表。每个子对象也有一个名为state的属性。我想知道的是,每个项目和他们的孩子在美国是快乐还是快乐

我对所有项目都这样做了(仅分析项目的状态):


我想知道哪种方法不仅对项目,而且对子项都是最好的方法。

您在这里寻找一些递归:

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

第一步:展平项目列表:

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))

我想这是正确的方法:

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 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
函数,如果您真的想这样做的话,您可以这样做。

在这个简单的例子中,我宁愿只为
for
循环设置一个基本的
,除非OP有更多的层要处理。或者更短:
all(item.state在['happy',happy']中,并且是快乐的(item.childs)对于item in items)
我认为OP所说的不止一个层。我假设他只提到了
2
,在这种情况下,递归会更慢,而且过多。我添加了一个for just-in-case:)
all(item.childs.state在['happy',happy']中)
我怀疑这是否有效
item.childs
是某种列表,没有属性
state
。我想这应该是
all(对于item.childs中的c,在[…]中的c.state)
if all(child.state in ['happy', 'cheerful'] for item in items for child in item+[item]):
   pass