通过聚合键使 Python 字典不区分大小写

Making Python dictionary case insensitive by aggregating keys

我有一本字典,由于字典区分大小写,所以有很多键彼此不同。我想将所有内容都放在一个小写键中,但将这些键的所有值汇总在一起。

我有类似的东西:

>>> data
{'Blue Car': 73, 'blue Car': 21, 'yellow car': 10, 'Yellow Car': 15, 'Red Car': 12, 'Red car': 17, 'red car': 10, 'Yellow car': 18}

输出应该是这样的:

>>> newData
{'blue car': 94, 'yellow car': 43, 'red car': 39}

使用默认字典:

from collections import defaultdict

newData = defaultdict(int)

for k in data:
    newData[k.lower()]+=data.get(k,0)

# {'blue car': 94, 'red car': 39, 'yellow car': 43}

希望对您有所帮助。

如何使用 defaultdict:

from collections import defaultdict
newData = defaultdict(int)
for k,v in data.iteritems():
    newData[k.lower()] += v

试试这个

def compress(data):
    newDict = dict()
    for key in data:
        newDict[key.lower()] = newDict.get(key.lower(), default=0) + data[key]
    return newDict

使用字典和集合理解:

>>> {x: sum(v for k, v in data.items() if k.lower()==x) for x in set(map(lambda x: x.lower(), data))}
{'red car': 39, 'blue car': 94, 'yellow car': 43}

或更用户友好:

SET = set(map(lambda x: x.lower(), data))
SUM = lambda x: sum(v for k, v in data.items() if k.lower()==x)
newData = {x: SUM(x) for x in SET}

# newData = {'red car': 39, 'blue car': 94, 'yellow car': 43}

解释:

SET = set(map(lambda x: x.lower(), data))

获取所有唯一的小写键,

SUM = lambda x: sum(v for k, v in data.items() if k.lower()==x)

returns data 中与唯一键匹配的键值的总和,以及

{x: SUM(x) for x in SET}

对于集合中的每个键,将把这个值作为配对的一部分与匹配键匹配。

我会继承 dict 并覆盖 __getitem____setitem__ 魔法方法

class NormalizedDict(dict):
    def __getitem__(self,key):
        return dict.__getitem__(self,key.lower())
    def __setitem__(self,key,value):
        return dict.__setitem__(self,key.lower(),value)

myDict = NormalizedDict()
myDict['aPPles'] =5
print myDict

当然,我们可以更进一步并为您自动求和

class NormalizedSumDict(NormalizedDict):
    def __setitem__(self,key,value):
        if key.lower() in self and type(self[key]) == type(value):
           try:
              value = value + self[key]
           except:
              pass
        NormalizedDict.__setitem__(self,key,value)
    def update(self,other):
        for k,v in other.items():
            self[k] = v

d = NormalizedSumDict()
d['aPPles']=5
d['Apples']=2
print d