Counter() 和字符串格式化

Counter() and string formatting

这个问题可以通过多种方式解决,但这个问题是关于多态性的。是否可以对 Counter() class 进行变形,因此当 Counter() 实例字符串格式中没有这样的键时 return 0?基本上需要使代码的最后一行工作。

from collections import Counter
VOWELS = 'aeiou'
context = 'Computing is cool'
cnt = Counter()
for letter in context:
    if letter in VOWELS:
        cnt[letter] += 1    
print('o-{o}, i-{i}, o-{o}'.format(**cnt))

# I'd like to make this line to work :
#print('a-{a}, e-{e}, i-{i}, o-{o}, u-{u}'.format(**cnt))

输出:

o-3, i-2, u-1

理想的输出:

a-0, e-0, i-2, o-3, u-1

when there is no such key in Counter() instance string formatting would return 0?

但这不是这里的问题。问题是 **cnt 只会解压现有元素。

你可以做的是用零计数初始化计数器 VOWELS 然后解压:

cnt = Counter({i:0 for i in 'aeiou'})

现在解包将拾取这些元素,即使它们有 0 计数。循环执行后,print:

print('a-{a}, e-{e}, i-{i}, o-{o}, u-{u}'.format(**cnt))

将 return 您想要的结果:

a-0, e-0, i-2, o-3, u-1

这不是更改 Counter 的情况。 ** 解包会将您的 Counter 转换为常规字典,对于缺少的键,它没有默认值 0。 (至少,它现在转换你的 Counter;早期版本的 there was a bug,所以如果你在早期的 Python 版本上尝试 ** 代码并且它似乎工作,那就是为什么。)

而不是 **,使用 format_map,这将直接使用您的 Counter

print('o-{o}, i-{i}, o-{o}'.format_map(cnt))