给定一个包含字符串键和整数值的字典,最快的方法是什么
- 将每个键拆分成一个字符串类型的键元组
- 然后附加一个特殊的子字符串
</w>
到元组中的最后一项
给定:
counter = {'The': 6149,
'Project': 205,
'Gutenberg': 78,
'EBook': 5,
'of': 39169,
'Adventures': 2,
'Sherlock': 95,
'Holmes': 198,
'by': 6384,
'Sir': 30,
'Arthur': 18,
'Conan': 3,
'Doyle': 2,}
目标是实现:
counter = {('T', 'h', 'e</w>'): 6149,
('P', 'r', 'o', 'j', 'e', 'c', 't</w>'): 205,
('G', 'u', 't', 'e', 'n', 'b', 'e', 'r', 'g</w>'): 78,
('E', 'B', 'o', 'o', 'k</w>'): 5,
('o', 'f</w>'): 39169,
('A', 'd', 'v', 'e', 'n', 't', 'u', 'r', 'e', 's</w>'): 2,
('S', 'h', 'e', 'r', 'l', 'o', 'c', 'k</w>'): 95,
('H', 'o', 'l', 'm', 'e', 's</w>'): 198,
('b', 'y</w>'): 6384,
('S', 'i', 'r</w>'): 30,
('A', 'r', 't', 'h', 'u', 'r</w>'): 18,
('C', 'o', 'n', 'a', 'n</w>'): 3,
('D', 'o', 'y', 'l', 'e</w>'): 2,}
一种方法是
- 遍历计数器并
- 将除最后一个字符以外的所有字符转换为元组
- 添加到元组并创建一个外部元组
- 并将元组键分配给计数
我试过了
{(tuple(k[:-1])+(k[-1]+'</w>',) ,v) for k,v in counter.items()}
更详细的形式:
new_counter = {}
for k, v in counter.items():
left = tuple(k[:-1])
right = tuple(k[-1]+'w',)
new_k = (left + right,)
new_counter[new_k] = v
有更好的方法吗?
关于添加元组并将其转换为外部元组。 为什么允许这样做?元组不应该是不可变的吗?
最佳答案
我建议对您的解决方案稍作修改。而不是使用 您可以使用元组解包的元组构造函数:
>>> {(*a[:-1],f'a[-1]</w>',):b for a,b in counter.items()}
与 tuple
构造函数相比,使用元组解包的好处是您将获得更好的性能。我将通过使用 timeit
对此进行更多阐述。我将使用随机生成的 dict
。 dict
中的每个键都有 2 个随机选择的小写字母字符,每个值都是 0-100 范围内的整数。对于所有这些基准测试,我使用的是 Python 3.7.0
dict 中有 100 个元素的基准
$ python -m timeit -s "import random" -s "import string" -s "counter = {''.join(random.sample(string.ascii_lowercase,2)): random.randint(0,100) for _ in range(100)}" "{(*a[:-1],f'a[-1]</w>',):b for a,b in counter.items()}
$ 10000 loops, best of 5: 36.6 usec per loop
$ python -m timeit -s "import random" -s "import string" -s "counter = {''.join(random.sample(string.ascii_lowercase,2)): random.randint(0,100) for _ in range(100)}" "{tuple(key[:-1])+(key[-1]+'</w>',):value for key,value in counter.items()}"
$ 5000 loops, best of 5: 59.7 usec per loop
dict 中有 1000 个元素的基准
$ python -m timeit -s "import random" -s "import string" -s "counter = {''.join(random.sample(string.ascii_lowercase,2)): random.randint(0,100) for _ in range(1000)}" "{(*a[:-1],f'a[-1]</w>',):b for a,b in counter.items()}"
$ 1000 loops, best of 5: 192 usec per loop
$ python -m timeit -s "import random" -s "import string" -s "counter = {''.join(random.sample(string.ascii_lowercase,2)): random.randint(0,100) for _ in range(1000)}" "{tuple(key[:-1])+(key[-1]+'</w>',):value for key,value in counter.items()}"
$ 1000 loops, best of 5: 321 usec per loop
带有问题的字典的基准测试
$ python -m timeit -s "import random" -s "import string" -s "counter = counter = {'The': 6149, 'Project': 205, 'Gutenberg': 78, 'EBook': 5, 'of': 39169, 'Adventures': 2, 'Sherlock': 95, 'Holmes': 198, 'by': 6384, 'Sir': 30, 'Arthur': 18, 'Conan': 3,'Doyle': 2}" "{(*a[:-1],f'a[-1]</w>',):b for a,b in counter.items()}"
$ 50000 loops, best of 5: 7.28 usec per loop
$ python -m timeit -s "import random" -s "import string" -s "counter = counter = {'The': 6149, 'Project': 205, 'Gutenberg': 78, 'EBook': 5, 'of': 39169, 'Adventures': 2, 'Sherlock': 95, 'Holmes': 198, 'by': 6384, 'Sir': 30, 'Arthur': 18, 'Conan': 3,'Doyle': 2}" "{tuple(key[:-1])+(key[-1]+'</w>',):value for key,value in counter.items()}"
$ 20000 loops, best of 5: 11 usec per loop
关于python - 将字典键拆分为字符串类型的元组并将另一个字符串附加到元组中的最后一项的最快方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54017546/