Python+Revit中优化细节项名称部分匹配过滤逻辑的问询
简化Revit中细节项的筛选逻辑
我在Python与Revit环境中工作,拥有一批带名称参数的detail items(细节项)列表,需要筛选出名称与给定字符串列表中任一内容部分匹配的细节项。目前已有可行实现,但可读性欠佳,希望简化逻辑。
现有可行代码
filtered_detail_items = filter(lambda x: filter_partial_match( key = x.LookupParameter('DMER_Panel_Name').AsString(), partial_keywords = ['TAP BOX', 'VFD', 'CONTROL PANEL', 'DISC'], inclusive = False), detail_items)
def filter_partial_match(key, partial_keywords, inclusive = True): # 支持传入单个字符串或字符串列表,单个字符串自动转成列表 if type(partial_keywords) is not list: partial_keywords = [ partial_keywords ] match_found = False if any(x in key for x in partial_keywords): match_found = True if inclusive: return match_found else: return not match_found
尝试的错误简化代码
filtered_detail_items = [(lambda x: (if any(y in x.LookParameter('DMER_Panel_Name').AsString() for y in ['TAP BOX', 'VFD', 'CONTROL PANEL', 'DISC']): x)) for x in detail_items ]
正确的简化方案
问题分析
你尝试的代码存在两个问题:
- 拼写错误:
LookParameter应为LookupParameter - 语法错误:lambda表达式中不能直接用
if语句返回对象,列表推导式的逻辑写法有误
方案1:直接用列表推导式实现(推荐)
把筛选逻辑直接内联,抽离关键词常量提升可读性,同时实现原代码的反向筛选(排除包含关键词的项):
# 抽离关键词为常量,方便后续维护 TARGET_KEYWORDS = ['TAP BOX', 'VFD', 'CONTROL PANEL', 'DISC'] filtered_detail_items = [ item for item in detail_items if not any(kw in item.LookupParameter('DMER_Panel_Name').AsString() for kw in TARGET_KEYWORDS) ]
方案2:简化原函数保留灵活性
如果需要保留原函数支持单个关键词、切换包含/排除的特性,可以简化函数逻辑:
def filter_partial_match(key, partial_keywords, inclusive=True): # 统一处理关键词为列表 keywords = partial_keywords if isinstance(partial_keywords, list) else [partial_keywords] # 直接用any的返回值判断匹配 has_match = any(kw in key for kw in keywords) return has_match if inclusive else not has_match # 调用时更简洁 filtered_detail_items = filter( lambda x: filter_partial_match( x.LookupParameter('DMER_Panel_Name').AsString(), ['TAP BOX', 'VFD', 'CONTROL PANEL', 'DISC'], inclusive=False ), detail_items )
方案3:用生成器表达式节省内存
如果detail items数量很大,用生成器表达式替代列表推导式,避免一次性加载所有结果到内存:
TARGET_KEYWORDS = ['TAP BOX', 'VFD', 'CONTROL PANEL', 'DISC'] filtered_detail_items = ( item for item in detail_items if not any(kw in item.LookupParameter('DMER_Panel_Name').AsString() for kw in TARGET_KEYWORDS) )
内容的提问来源于stack exchange,提问作者mybluesock
相关产品推荐
相关产品推荐

