2017-05-09 139 views
2

嗯......我有一个简单的请求,建立一个条目,即时过滤条目列表。 (想想编辑器自动完成功能)如何使用正则表达式快速过滤列表?

请求是在整个列表上支持正则表达式过滤器,并只显示匹配的条目。

例如,

该列表包含:

abc.efg.hij.entry 
abc.ddd.hij.entry2 
hij.some.value.entry 

打字在条目

Value : List 
hij  : abc.efg.hij.entry, abc.ddd.hij.entry2, hij.some.value.entry 
ddd  : abc.ddd.hij.entry2 
dd*entry : abc.ddd.hij.entry2 
val  : hij.some.value.entry 

这里是我使用过滤列表的代码:

regex = re.compile(r"{0}".format(entry_value), re.IGNORECASE) 
display_list = list(filter(regex.search, display_list)) 

现实生活里st包含〜300K字符串的条目(每条最多100个字符),考虑到GUI响应时间,以上的性能非常差。 我已经对我的真实测试案例进行了剖析,并且它为输入中的每个键输入产生〜0.8s。

有没有更快的方法?

回答

1

如果您正在对包含300,000个项目的普通python列表进行正则表达式模式匹配,它自然会变得很慢。另外,如果您要在列表框中显示300,000个项目,则显示所有这些项目的速度会很慢。

你最好的选择可能是选择一个更好的数据结构。例如,在我的系统上,我可以在大约250ms内针对300,000个项目运行过滤器,但对内存为300,000行的sqlite数据库的查询需要大约一半的时间。无论哪种情况,如果结果非常大(例如,如果全部300,000匹配),它可以增加另一秒来完全更新显示器

当然,sqlite不支持开箱即用的正则表达式,但是您可以将一些常见模式转换为sql模式(例如:'foo。* bar'可以转换为'foo%bar')。有关sqlite和正则表达式的更多信息,请参阅How do I use regex in a SQLite query?

另一种使用的策略是不搜索每个键入的字符。等待用户暂停输入。因此,例如,如果他们键入“Lorem”,则不需要搜索“L”,然后搜索“Lo”,然后搜索“Lor”等。相反,安排搜索发生在100毫秒内,并与每次按键您都可以重新安排搜索。这将防止搜索速度变慢,同时仍然给用户看起来相当快速的结果。

+0

感谢 - 优秀的提示 - 我将我的内存数据库移至sqlite3 - 过滤时间降至100ms以下(x8优化)。至于列表框本身,这已经被优化了(我只显示过滤列表的一小部分,并让用户浏览它...) – NirMH