过于复杂的列表理解?

时间:2013-01-08 03:57:59

标签: python list-comprehension

我有一个对象列表,其中包含一个名为mgmt_classes的属性,该属性本身就是一个列表。

systems = [System, System, System,...]
System.mgmt_classes = ['foo','bar']

我想识别系统列表中具有名为'foo'的mgmt_class的系统对象。我想出了两种方法,但我不喜欢任何一种。

丑陋的列表理解

matching = [system for system in systems 
            if len([mc for mc in system.mgmt_classes 
                    if re.search(search, mc)]) > 0]

丑陋的嵌套循环

matching = []
for system in systems:
    for mgmt_class in system.mgmt_classes:
        if re.search(search, mgmt_class):
            matching.append(system)

我不喜欢其中任何一个。有更优雅的方式吗?我的直觉告诉我,丑陋的嵌套循环将是两者中更好的解决方案,因为它更容易理解。

修改

我希望能够在mgmt_classes中搜索部分术语,所以'foo'会让我'食物'或'足球'。例如。

2 个答案:

答案 0 :(得分:4)

如果您的匹配条件很复杂,请考虑将其分解为另一个函数,例如:

systems = [System, System, System,...]
System.mgmt_classes = ['foo','bar']

def hasmatches(classes):
    return any(re.search(search, mc) for mc in classes)

matching = [system for system in systems
    if hasmatches(system.mgmt_classes)]

hasmatches在第一次在类列表中找到匹配时返回True,否则返回False(如果它们都不匹配)。然后列表推导在每个系统上调用它并收集hasmatches评估为True的那些。

如果它真的像查找特定值一样简单,则丢失正则表达式以支持直接字符串比较:

matching = [system for system in systems if 'foo' in system.mgmt_classes]

答案 1 :(得分:4)

matching = [system for system in systems if 'foo' in system.mgmt_classes]

if语句检查属性'foo'中是否mgmt_classes - 比使用正则表达式简单得多。

但是,如果您的条件需要使用正则表达式,请使用:

matching = [system for system in systems if any(re.search('foo', i) for i in system.mgmt_classes)]

这只是柯克答案的一个版本。