让我们看看 for 循环到底有多“慢”。我的解决方案:
dic2 = {}
for k, (dic2[k], _) in dic.items():
pass
用您的玩具词典进行基准测试:
600 ns 602 ns 603 ns U12_Forward_1
1019 ns 1025 ns 1027 ns U12_Forward_2
1347 ns 1350 ns 1355 ns user1740577
441 ns 442 ns 443 ns dont_talk_just_code
按照您的评论,使用包含 12k 个项目的“大”字典进行基准测试:
1412624 ns 1414927 ns 1418089 ns U12_Forward_1
1687464 ns 1690134 ns 1696759 ns U12_Forward_2
1961205 ns 1986729 ns 2005884 ns user1740577
1248901 ns 1260306 ns 1261295 ns dont_talk_just_code
以上是在on tio.run完成的,我使用它是因为它的高速和速度稳定性。遗憾的是,它没有提供 Marco 的回答所需的 cytoolz,所以我不能包括在内。然后@user1740577 指责我撒谎,因为我没有包含它,所以这里是 replit.com 的结果,我可以(请注意,如果你在那里运行它并且没有付费帐户,你的时间会慢一些) :
475 ns 476 ns 484 ns U12_Forward_1
804 ns 805 ns 807 ns U12_Forward_2
1075 ns 1079 ns 1082 ns user1740577
442 ns 444 ns 448 ns Marco_DG
360 ns 360 ns 360 ns dont_talk_just_code
1060461 ns 1061449 ns 1071588 ns U12_Forward_1
1294079 ns 1330157 ns 1706065 ns U12_Forward_2
1593082 ns 1594114 ns 1596703 ns user1740577
1268663 ns 1274264 ns 1286715 ns Marco_DG
964445 ns 965971 ns 966333 ns dont_talk_just_code
完整的基准代码(也有at replit:
from timeit import repeat
from functools import partial
from operator import itemgetter
from cytoolz import valmap , first
def U12_Forward_1(dic):
return {k: v[0] for k, v in dic.items()}
def U12_Forward_2(dic):
return dict(zip(dic, map(itemgetter(0), dic.values())))
def user1740577(dic):
return dict(zip(dic.keys(),list(list(zip(*dic.values()))[0])))
def Marco_DG(dic):
return valmap(first, dic)
def dont_talk_just_code(dic):
dic2 = {}
for k, (dic2[k], _) in dic.items():
pass
return dic2
funcs = U12_Forward_1, U12_Forward_2, user1740577, Marco_DG, dont_talk_just_code
def bench(dic, number):
expect = funcs[0](dic)
for func in funcs:
result = func(dic)
print(result == expect, func.__name__)
print()
for _ in range(3):
for func in funcs:
ts = sorted(repeat(partial(func, dic), number=number))[:3]
print(*('%7d ns ' % (t / number * 1e9) for t in ts), func.__name__)
print()
bench({'key1': [2,3], 'key2': [5,1], 'key3': [6,8]}, 100000)
bench({f'key{i}': [i,42] for i in range(12000)}, 30)