0

我有一个对象列表,其属性名为 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' 会让我得到 'food' 或 'football'。

4

2 回答 2

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]
于 2013-01-08T04:02:38.123 回答
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)]

这只是柯克答案的单行版本。

于 2013-01-08T04:03:27.013 回答