是否可以嵌套所有功能?

时间:2014-12-15 13:05:06

标签: python

我有一个名为 items 的对象列表。每个对象都有一个属性 state 和一个属性 children ,这是另一个对象列表。每个子对象还有一个名为 state 的属性。我想知道的是,每件物品及其子女是否处于快乐欢快的状态。

我和所有人一起做过(仅分析项目的状态):

if all(item.state in ['happy', 'cheerful'] for item in items):
   pass

我想知道哪种方法不仅可以用于物品,也可以用于儿童。

5 个答案:

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