我希望最大限度地优化这段代码的运行时间:
aDictionary= {"key":["value", "value2", ...
rests = \
list(map((lambda key: Resp(key=key)),
[key for key, values in
aDictionary.items() if (test1 in values or test2 in values)]))
使用python3。愿意尽可能多地记忆。
考虑将两个字典查找放在单独的进程上以加速(这有意义吗?)。欢迎任何其他优化想法
答案 0 :(得分:2)
对于初学者,当您已经使用列表推导时,没有理由使用map
,因此您可以将其删除,以及外部list
调用:
rests = [Resp(key=key) for key, values in aDictionary.items()
if (test1 in values or test2 in values)]
第二种可能的优化方法可能是将每个值列表转换为一组。这会花费最初的时间,但它会将您的查找(in
使用)从线性时间更改为恒定时间。您可能需要为此创建单独的辅助函数。类似的东西:
def anyIn(checking, checkingAgainst):
checkingAgainst = set(checkingAgainst)
for val in checking:
if val in checkingAgainst:
return True
return False
然后您可以将列表理解的结尾更改为
...if anyIn([test1, test2], values)]
但是,如果你检查的值超过两个,或者values
中的值列表很长,那么这可能是值得的。
答案 1 :(得分:2)
如果tests
足够多,那么切换到设置操作肯定会有所回报:
tests = set([test1, test2, ...])
resps = map(Resp, (k for k, values in dic.items() if not tests.isdisjoint(values)))
# resps this is a lazy iterable, not a list, and it uses a
# generator inside, thus saving the overhead of building
# the inner list.
将dict
值转换为集合将无法获得任何效果,因为转换为O(N)
且N
是所有values
列表的附加大小,而上述不相交的操作只会迭代每个values
,直到遇到testx
O(1)
次查找。
map
可能比理解更高效,例如如果key
可以用作Resp
的{{1}}中的第一个位置参数,但肯定不能用于lambda! (Python List Comprehension Vs. Map)。否则,生成器或理解会更好:
__init__