【发布时间】:2021-06-14 16:37:35
【问题描述】:
在试图找到过滤字典的最有效方法时,我偶然发现了一种奇怪的行为。
我做了4个测试,第一个按顺序过滤字典。
第二个使用规则组合进行单一过滤(这实际上是最有效的方式)。
然后,我尝试使其更通用,以便过滤器可以与任意数量的谓词一起使用,这些谓词最终可以是用户定义的,而不是硬编码的。
我意识到,将 predicated 与 all 组合比一个接一个地进行两个过滤效率低得多。
这能解释什么?这是性能很差的all() 函数吗?
您是否会建议任何其他方式以通用方式提高性能?
# TEST 1 (Took 1.717677354812622s)
y = {k:x for k,x in y.items() if x['id'] >= 3 }
y = {k:x for k,x in y.items() if x['name'].find('a') != -1 }
# TEST 2 (Took 1.411365032196045s)
y = {k:x for k,x in y.items() if x['id'] >= 3 and x['name'].find('a') != -1 }
# TEST 3 (Took 3.4738941192626953s)
predicates = [
lambda x: x['id'] >= 3,
lambda x: x['name'].find('a') != -1
]
y = {k:x for k,x in y.items() if all([f(x) for f in predicates]) }
# TEST 4 (Took 2.4156315326690674s)
predicates = [
lambda x: x['id'] >= 3,
]
y = {k:x for k,x in y.items() if predicates[0](x) }
predicates = [
lambda x: x['name'].find('a') != -1
]
y = {k:x for k,x in y.items() if predicates[0](x) }
测试台:
from var_dump import var_dump
import time
start_time = time.time()
for p in range(0,1000000):
users = {
1: {'id': 1, 'name': "toto"},
2: {'id': 2, 'name': "titi"},
3: {'id': 3, 'name': "tata"},
4: {'id': 4, 'name': "tutu"},
5: {'id': 5, 'name': "john"},
6: {'id': 6, 'name': "jane"}
}
y = users
#-> test goes here
print(y)
print("--- %s seconds ---" % (time.time() - start_time))
【问题讨论】:
-
all对每个 dict 值都应用两个 lambda,而在 TEST2 中,条件if x['id'] >= 3 and x['name'].find('a') != -1被延迟评估,x['name'].find('a')不评估 ids
标签: python performance dictionary filter dictionary-comprehension