【问题标题】:Combine same keys in dictionary ignoring case在字典中组合相同的键忽略大小写
【发布时间】:2021-05-09 17:15:52
【问题描述】:

我看了又看,但找不到我的问题的答案。我如何组合字典键而忽略它们的大小写。 例如说我有一本这样的字典。

dict = {'a':1,'A',2}

忽略大小写,这两个键是相同的字母。因此,我希望将它们结合起来最终得到一个看起来像这样的字典

dict = {'a':3}

输出键的大小写无关紧要。


目前我的代码如下所示。

s = "YazaAay"
freq = {i : s.count(i) for i in set(s)}

这将返回给我

{'A': 1, 'z': 1, 'Y': 1, 'a': 3, 'y': 1}

我想要的输出是这样的

{'a':4,'z':1,'y':2}

#大小写和顺序都不重要。

【问题讨论】:

    标签: python dictionary case-insensitive


    【解决方案1】:

    大小写折叠的简单解决方案通常是在字符串上调用lower()(或upper())。

    我还建议使用collections.Counter 而不是构建自己的逻辑来计算字母;它更高效(因为它只循环遍历字符串一次,而使用set()count() 的解决方案在每个唯一字母加上一次开始构建集合时循环遍历它)并且它使您的代码更简单。

    >>> s = "YazaAay"
    >>> import collections
    >>> collections.Counter(s.lower())
    Counter({'a': 4, 'y': 2, 'z': 1})
    

    如果您从字典而不是字符串开始,一种选择是使用join() 将字典转回字符串,然后使用.lower()Counter 应用完全相同的解决方案:

    >>> d = {'A': 1, 'z': 1, 'Y': 1, 'a': 3, 'y': 1}
    >>> collections.Counter(''.join(k * v for k, v in d.items()).lower())
    Counter({'a': 4, 'y': 2, 'z': 1})
    

    【讨论】:

    • 是的,我应该包括我正在使用collections 寻找的东西。但是对于有相同问题的其他用户,我想得到各种各样的问题会很简单。很好的答案。
    【解决方案2】:

    这里是不使用导入的解决方案。

    s = "YazaAay".lower()
    freq = {i: s.count(i) for i in sorted(s)}
    

    输出:

    {'a': 4, 'y': 2, 'z': 1}
    

    【讨论】:

    • 对于这么小的字符串来说这并不重要,但这甚至比 OP 的 set() 原始解决方案效率低;现在是 O(len(s)**2) 而不是 O(len(s) * len(set(s)))。
    【解决方案3】:

    在您的示例中,预先降低字符串可以规避您的问题。

    s = "YazaAay"
    freq = {i : s.count(i) for i in set(s.lower())}
    

    在更一般的情况下,如果您已经有一个混合大小写的字典,您可以使用默认字典重建:

    from collections import defaultdict
    
    d = {'A': 1, 'z': 1, 'Y': 1, 'a': 3, 'y': 1}
    
    new_dict = defaultdict(int)
    for key, val in d.items():
        new_dict[key.lower()] += val
    

    这会给你

    defaultdict(int, {'a': 4, 'z': 1, 'y': 2})
    

    【讨论】:

      【解决方案4】:

      这是一个简单的解决方案。

      # Original dictionary
      d = {'A': 1, 'z': 1, 'Y': 1, 'a': 3, 'y': 1}
      
      # Split the dictionary into 2 parts
      lower_case_keys = dict((key, value) for key, value in d.items() if key.islower())
      Output: {'z': 1, 'a': 3, 'y': 1}
      
      upper_case_keys = dict((key, value) for key, value in d.items() if key.isupper())
      Output: {'A': 1, 'Y': 1}
      
      # Convert lower_case_keys to upper case for uniformity
      lower_case_keys_to_upper_case = dict((key.upper(), value) for key, value in d.items())
      output: {'A': 3, 'Z': 1, 'Y': 1}
      
      from collections import Counter
      final_dict = dict(Counter(lower_case_keys_to_upper_case) + Counter(upper_case_keys))
      Output: {'A': 4, 'Z': 1, 'Y': 2}
      

      所有这些都可以组合成一个函数。

      from collections import Counter
      def get_case_insensitive_sum(d):
          lower_case_keys = dict((key, value) for key, value in d.items() if key.islower())
          upper_case_keys = dict((key, value) for key, value in d.items() if key.isupper())
          lower_case_keys_to_upper_case = dict((key.upper(), value) for key, value in d.items())
          final_dict = dict(Counter(lower_case_keys_to_upper_case) + Counter(upper_case_keys))
          print(final_dict)
      
      d = {'A': 1, 'z': 1, 'Y': 1, 'a': 3, 'y': 1}
      get_case_insensitive_sum(d)
      Output: {'A': 4, 'Z': 1, 'Y': 2}
      

      【讨论】:

      • 如果你从字典开始,你可以通过''.join(key * value for key, value in d.items()).lower()把它变成一个大小写折叠的字符串。 :) 没有理由将它一分为二,以后再重新组合!
      猜你喜欢
      • 2012-09-11
      • 1970-01-01
      • 2013-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-15
      • 2022-08-17
      • 2016-06-06
      相关资源
      最近更新 更多