将字典复制到 defaultdict
Copying a dictionary to defaultdict
我想高效地将字典复制到 defaultdict
。
这是我的代码:
[In] from collections import defaultdict
[In] new_dict = {'a': 1, 'b': 2, 'c': 3, 'e':4, 'f':5}
[In] def_dict = defaultdict(list)
[In] timeit for k, v in new_dict.items(): def_dict[k].append(v)
[Out] 1000000 loops, best of 3: 910 ns per loop
我想改进它的性能。
欢迎提出任何建议。
我坚持我的建议,即使用 def_dict[k] = [v]
会比 def_dict[k].append(v)
快,根据我自己的测试发现它快了将近两倍。
下面是我用来确定这一点的完整基准测试代码。我还尝试了其他几种可能性,但 none 更好。
Python 3.5.0 和 Python 2.7.10 都获得了相似的结果。
from __future__ import print_function
import sys
from textwrap import dedent
import timeit
N = 1000000 # number of executions of each "algorithm"
R = 3 # number of Repeations of executions
# common setup for all algorithms (not timed)
setup = dedent("""
from collections import defaultdict
new_dict = {'a': 1, 'b': 2, 'c': 3, 'e': 4, 'f': 5}
""")
algorithms = {
"def_dict[k].append(v)": dedent("""
def_dict = defaultdict(list)
for k, v in new_dict.items(): def_dict[k].append(v)
"""),
"def_dict[k] = [v]": dedent("""
def_dict = defaultdict(list)
for k, v in new_dict.items(): def_dict[k] = [v]
"""),
"defaultdict(list, <gen-xprsn>)": dedent("""
def_dict = defaultdict(list, ((k, [v]) for k, v in new_dict.items()))
"""),
"defaultdict(list, <dict-comp>)": dedent("""
def_dict = defaultdict(list, {k:[v] for k, v in new_dict.items()})
"""),
}
# collecting results of executing and timing each algorithm snippet
timings = [
(label,
min(timeit.repeat(algorithms[label], setup=setup, repeat=R, number=N)),
) for label in algorithms
]
# display results
print('fastest to slowest execution speeds (Python {}.{}.{})\n'.format(
*sys.version_info[:3]),
' ({:,d} executions, best of {:d} repetitions)\n'.format(N, R))
longest = max(len(timing[0]) for timing in timings) # length of longest label
ranked = sorted(timings, key=lambda t: t[1]) # ascending sort by execution time
fastest = ranked[0][1]
for timing in ranked:
print("{:>{width}} : {:9.6f} secs, rel speed {:4.2f}x, {:6.2f}% slower".
format(timing[0], timing[1], round(timing[1]/fastest, 2),
round((timing[1]/fastest - 1) * 100, 2), width=longest))
以下是 运行 在我的系统上的结果:
fastest to slowest execution speeds (Python 3.5.0)
(1,000,000 executions, best of 3 repetitions)
def_dict[k] = [v] : 0.977644 secs, rel speed 1.00x, 0.00% slower
defaultdict(list, <dict-comp>) : 1.330040 secs, rel speed 1.36x, 36.05% slower
defaultdict(list, <gen-xprsn>) : 1.761532 secs, rel speed 1.80x, 80.18% slower
def_dict[k].append(v) : 1.929081 secs, rel speed 1.97x, 97.32% slower
我想高效地将字典复制到 defaultdict
。
这是我的代码:
[In] from collections import defaultdict
[In] new_dict = {'a': 1, 'b': 2, 'c': 3, 'e':4, 'f':5}
[In] def_dict = defaultdict(list)
[In] timeit for k, v in new_dict.items(): def_dict[k].append(v)
[Out] 1000000 loops, best of 3: 910 ns per loop
我想改进它的性能。 欢迎提出任何建议。
我坚持我的建议,即使用 def_dict[k] = [v]
会比 def_dict[k].append(v)
快,根据我自己的测试发现它快了将近两倍。
下面是我用来确定这一点的完整基准测试代码。我还尝试了其他几种可能性,但 none 更好。
Python 3.5.0 和 Python 2.7.10 都获得了相似的结果。
from __future__ import print_function
import sys
from textwrap import dedent
import timeit
N = 1000000 # number of executions of each "algorithm"
R = 3 # number of Repeations of executions
# common setup for all algorithms (not timed)
setup = dedent("""
from collections import defaultdict
new_dict = {'a': 1, 'b': 2, 'c': 3, 'e': 4, 'f': 5}
""")
algorithms = {
"def_dict[k].append(v)": dedent("""
def_dict = defaultdict(list)
for k, v in new_dict.items(): def_dict[k].append(v)
"""),
"def_dict[k] = [v]": dedent("""
def_dict = defaultdict(list)
for k, v in new_dict.items(): def_dict[k] = [v]
"""),
"defaultdict(list, <gen-xprsn>)": dedent("""
def_dict = defaultdict(list, ((k, [v]) for k, v in new_dict.items()))
"""),
"defaultdict(list, <dict-comp>)": dedent("""
def_dict = defaultdict(list, {k:[v] for k, v in new_dict.items()})
"""),
}
# collecting results of executing and timing each algorithm snippet
timings = [
(label,
min(timeit.repeat(algorithms[label], setup=setup, repeat=R, number=N)),
) for label in algorithms
]
# display results
print('fastest to slowest execution speeds (Python {}.{}.{})\n'.format(
*sys.version_info[:3]),
' ({:,d} executions, best of {:d} repetitions)\n'.format(N, R))
longest = max(len(timing[0]) for timing in timings) # length of longest label
ranked = sorted(timings, key=lambda t: t[1]) # ascending sort by execution time
fastest = ranked[0][1]
for timing in ranked:
print("{:>{width}} : {:9.6f} secs, rel speed {:4.2f}x, {:6.2f}% slower".
format(timing[0], timing[1], round(timing[1]/fastest, 2),
round((timing[1]/fastest - 1) * 100, 2), width=longest))
以下是 运行 在我的系统上的结果:
fastest to slowest execution speeds (Python 3.5.0)
(1,000,000 executions, best of 3 repetitions)
def_dict[k] = [v] : 0.977644 secs, rel speed 1.00x, 0.00% slower
defaultdict(list, <dict-comp>) : 1.330040 secs, rel speed 1.36x, 36.05% slower
defaultdict(list, <gen-xprsn>) : 1.761532 secs, rel speed 1.80x, 80.18% slower
def_dict[k].append(v) : 1.929081 secs, rel speed 1.97x, 97.32% slower