Python在命名属性上嵌套选择

时间:2014-01-17 20:46:12

标签: python python-3.x

我有一组列表,以便我有一个类似这样的数组

class engine:
    engines = []
    def __init__(self):
          this.modules = []

class module:
    def __init__(self,flag):
          this.someFlag = flag

这样我就有了一个引擎列表,而这些引擎又有一个模块列表作为每个引擎的'modules'属性。

e.g:

EngineA在EngineA.modules下有ModuleA和ModuleB EngineC在EngineC.modules下有ModuleC和ModuleD

我想搜索我的引擎列表,以便在列表中获得符合特定条件的所有模块

例如:从所有引擎中选择engine.modules,其中someFlag ='foo';

选择我知道的所有引擎:

engines = [e for e in engine.engines]

但如何选择'e'中的模块?

我试着像:

 [m for m in e.modules for e in engine.engines]

但我被告知e不存在。

4 个答案:

答案 0 :(得分:3)

试试这个:

[m for e in engine.engines for m in e.modules]

来自PEP 202

  

形式[... for x ... for y ...]嵌套,最后一个索引变化   最快,就像嵌套for循环一样。

答案 1 :(得分:3)

list comprehension中的for ... in ...子句应该与它们是正常for循环的顺序相同。

意思是,你的代码需要像这样编写为列表理解:

[m for e in engine.engines for m in e.modules]

因为它将使用for-loops编写:

lst = []
for e in engine.engines:
    for m in e.modules:
        lst.append(m)

您可以在PEP 202中了解这一点,其中介绍了列表推导的概念:

  

建议的解决方案

     

建议允许条件构造列表文字   使用for和if子句。他们会以同样的方式筑巢   循环和if语句现在嵌套。

答案 2 :(得分:2)

您可以使用列表推导的if部分。所以:

[m for e in engine.engines for m in e.modules if m.someflag == 'foo']

答案 3 :(得分:2)

尽管我喜欢list comps,但我要说的是将一些功能分解为单独的功能可能是有意义的。具体来说,我认为除了列表comp之外,实际上还有在每个模块上运行的检查代码是有意义的。

contains_module = lambda e, f: [m for m in e if m.someFlag == f]

此时,要实现所需的查询,您只需执行以下操作:

engines_with module = [e for e in engine.engines if contains_module(e, flag)]

如果你想要这些模块,你可以简化结果:

flatten = lambda l: [item for sublist in l for item in sublist]
modules_with_flag = flatten([contains_module(e, flag) for e in engine.engines])