如何使用Python的itertools移除以指定字符串列表开头的行
用itertools实现前缀过滤需求?
问题说明
给定两组数据:
kill = ['err A', 'err B', 'err C'] lines = ['keep A', 'err B foo', 'err A bar', 'keep B', 'err C foobar']
需要筛选出lines中不以kill里任意元素开头的行,预期输出:
['keep A', 'keep B']
已有嵌套循环的解法:
result = [] for e in lines: ok = True for k in kill: if e.startswith(k): ok = False if ok: result.append(e)
想知道能不能用itertools库实现相同需求。
解决方案:当然可以,推荐两种写法
写法1:列表推导式 + itertools.all()
核心思路是对每一行,检查所有kill元素都不是它的前缀,用itertools.all()替代内层循环的判断,代码更简洁:
from itertools import all kill = ['err A', 'err B', 'err C'] lines = ['keep A', 'err B foo', 'err A bar', 'keep B', 'err C foobar'] result = [line for line in lines if all(not line.startswith(k) for k in kill)] print(result)
运行后输出就是预期的['keep A', 'keep B']。
这里all()会逐个检查kill里的元素:只要有一个元素是当前行的前缀,not line.startswith(k)就会是False,all()直接返回False,该行被过滤;只有所有kill元素都不匹配前缀时,all()才返回True,该行被保留。
写法2:itertools.filterfalse() + any()
如果喜欢用过滤函数的写法,也可以用filterfalse()配合any()实现:
from itertools import filterfalse kill = ['err A', 'err B', 'err C'] lines = ['keep A', 'err B foo', 'err A bar', 'keep B', 'err C foobar'] def should_remove(line): # 判断当前行是否需要被移除(即存在kill元素是它的前缀) return any(line.startswith(k) for k in kill) result = list(filterfalse(should_remove, lines)) print(result)
这个逻辑是用filterfalse()把需要移除的行过滤掉,剩下的就是符合要求的内容。
内容的提问来源于stack exchange,提问作者buhtz
相关产品推荐
相关产品推荐

