如何将字典中的键转换为大写并在生成的字典中添加相同键的值?

8

我有一个像这样的字典:

d = {'A':110, 'a':100, 'T':50, 't':5}

我希望将键值转换为大写,并结合 A+aT+t 并添加它们的值,以便生成的字典如下所示:

d = {'A': 210, T: 55}

这是我尝试的内容:

for k, v in d.items():
    k.upper(), v

结果如下:

('A', 110)
('A', 100)
('T', 50)
('t', 5)

这看起来像是元组,但我想将它转换为字典,所以我尝试编写了一个函数:

def Upper(d):
    for k, v in d.items:
        k.upper(), v
    return d

但它返回未更改的字典。

在我将键改为大写后,我找到了如何添加字典中键的值的解决方案:

dict([(x, a[x] + b[x]) if (x in a and x in b) else (x, a[x]) if (x in a) else (x, b[x])

但首先我需要将键转换为大写!


使用Python时,您应该更加注意缩进。您“我尝试过的内容”中的两个示例都存在缩进错误,这将完全阻止代码运行。 - supervacuo
7个回答

14
计数器(Counter)非常好用。
>>> d = {'A':110, 'a':100, 'T':50, 't':5}
>>> from collections import Counter
>>> c = Counter()
>>> for k,v in d.items():
...     c.update({k.upper(): v})
... 
>>> c
Counter({'A': 210, 'T': 55})

1
@edg,你至少需要Python2.7才能使用“Counter”。 - John La Rooy

6

upper()方法不会改变任何内容。你可以使用以下代码:

def capitalize_keys(d):
    result = {}
    for key, value in d.items():
        upper_key = key.upper()
        result[upper_key] = result.get(upper_key, 0) + value
    return result

这个很好运行,但为什么新字典没有存储在d中呢? - edg
@edg:可以编写一个更改代码(http://pastebin.com/FHgv9Y5p)的程序,但这种实现方式不够透明,而且执行的操作数量大致相同。使用上述函数,您可以编写`d = capitalize_keys(d)`。 - citxx

2

defaultdict很有用:

>>> from collections import defaultdict
>>> d = {'A':110, 'a':100, 'T':50, 't':5}
>>> new_d = defaultdict(int)
>>> for key, val in d.iteritems():
...     new_d[key.upper()] += val
...
>>> dict(new_d)
{'A': 210, 'T': 55}

当我尝试使用defaultdict('new_d = defaultdict(0)')时,我会收到以下错误消息: - edg
追踪(Traceback)(最近的一个调用在最前面): 文件“<stdin>”,第1行,在<module>中: TypeError: 第一个参数必须是可调用的 - edg
这是因为它应该是 defaultdict(int) - hochl
@edg已经修复,现在在初始化defaultdict实例时请使用int而不是0 - Roman Bodnarchuk

1

我认为你需要重新构建你的字典。例如:

from collections import defaultdict

d={'A':110, 'a':100, 'T':50, 't':5}

def upper(d):
        nd=defaultdict(int)
        for k, v in d.iteritems():
                nd[k.upper()]+=v
        return dict(nd)

print d
print upper(d)

输出:

{'A': 110, 'a': 100, 'T': 50, 't': 5}
{'A': 210, 'T': 55}

或者使用@citxx的解决方案,使用result.get(upper_key, 0) + value,从而避免使用defaultdict。

谢谢,使用该函数后,它会返回如下的新字典:defaultdict(<type 'int'>, {'A': 110, 'T': 50})。但是,当我查看d(原始字典)中的内容时,仍然是旧的字典...我该如何将新的字典返回/存储到d中? - edg
只需将 d 赋值为 d=upper(d),问题就解决了。 - hochl

1
d = {'A':110, 'a':100, 'T':50, 't':5}
{i.lower(): d.get(i.lower(),0)+d.get(i.upper(),0) for i in d.keys()}
// {'a': 210, 't': 55}

如果您想使用大写字母键,则使用:

{i.upper(): d.get(i.lower(),0)+d.get(i.upper(),0) for i in d.keys()}
// {'A': 210, 'T': 55}

输出:


请不要仅仅发布代码作为答案,还要提供解释您的代码是如何解决问题的。带有解释的答案通常更有帮助和更高质量,并且更有可能吸引赞同。 - Tyler2P

1

通过这个功能(已更正):

>>> def upper_kdict(d):
...     r = {}
...     for k, v in d.items():
...             K = k.upper()
...             r[K] = v if not r.__contains__(K) else v + r[K]
...     return r
... 
>>> 
>>> d = {'a': 100, 'A': 110, 'b': 20, 'B': 1000, 'C': 150, 'c': 100, 'd': 180}
>>> upper_kdict(d)
{'A': 210, 'C': 250, 'B': 1020, 'D': 180}

“并且将 A+a 和 T+t 结合并添加它们的值”这意味着 upper_dict(dict(a=1, A=1)) 应返回 {'A': 2};但是您的函数返回了 {'A': 1} - supervacuo
请修复这个限制或者删除你的答案。 - supervacuo

0
使用非常长的字典推导式:
d = {'A':110, 'a':100, 'T':50, 't':5}
d = dict((k, v + d.get(k.lower(), 0)) if (k == k.upper()) 
    else (k.upper(), v) for (k, v) in d.items() 
    if ((k == k.upper()) or (k == k.lower() and not (k.upper() in d))))
print d

输出:

{'A': 210, 'T': 55}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接