Python中将字典转换为小写

67

我想在一个字典中这样做:

"My string".lower()

是否有内置函数,还是应该使用循环?


1
对于键、值或两者,您需要翻译哪个? - hasen
14个回答

107

您需要使用循环或列表/生成器推导式。如果您想将所有键和值都转换为小写,可以执行以下操作:

dict((k.lower(), v.lower()) for k,v in {'My Key':'My Value'}.iteritems())

如果您只想将键转换为小写,可以这样做:

dict((k.lower(), v) for k,v in {'My Key':'My Value'}.iteritems())

生成器表达式(在上面使用)通常用于构建字典;我一直在使用它们。具有循环推导的所有表现力,但没有任何内存开销。


5
假设这些键是字符串。如果你使用数字作为键,它将失败。 - lorenzog
31
在Python 3中,dict.iteritems()已被移除,请改用dict.items() - Løiten
如果有一个项目'A':4和'a':5,该怎么办呢?如何将它们相加,使其变为'a':9? - Ahmed Nawaz Khan

16
如果您希望将多层嵌套的字典(JSON格式)中的键和值转换为小写,这可能会有所帮助。 需要支持字典推导式,并且应该是在Python 2.7中进行。
dic = {'A':['XX', 'YY', 'ZZ'],
       'B':(u'X', u'Y', u'Z'),
       'C':{'D':10,
            'E':('X', 'Y', 'Z'),
            'F':{'X', 'Y', 'Z'}
           },
       'G':{'X', 'Y', 'Z'}
      }

PYTHON2.7 -- 也支持OrderedDict

def _lowercase(obj):
    """ Make dictionary lowercase """
    if isinstance(obj, dict):
        t = type(obj)()
        for k, v in obj.items():
            t[k.lower()] = _lowercase(v)
        return t
    elif isinstance(obj, (list, set, tuple)):
        t = type(obj)
        return t(_lowercase(o) for o in obj)
    elif isinstance(obj, basestring):
        return obj.lower()
    else:
        return obj 

PYTHON 3.6

def _lowercase(obj):
    """ Make dictionary lowercase """
    if isinstance(obj, dict):
        return {k.lower():_lowercase(v) for k, v in obj.items()}
    elif isinstance(obj, (list, set, tuple)):
        t = type(obj)
        return t(_lowercase(o) for o in obj)
    elif isinstance(obj, str):
        return obj.lower()
    else:
        return obj

1
在Python 3中,使用items()代替iteritems(),并使用str代替basestring。如果您不想降低值(在我的情况下它们是列表),只需删除检查列表的elif子句(反正列表不能作为键)。 - lava-lava
这个解决方案适用于多层嵌套的字典。我将按照@lava-lava的建议添加解决方案,并添加检查集合和元组的功能。在2.7版本中,为了支持OrderedDict(在3.0中dict是有序的),需要对dict创建进行小的修改。 - vldbnc

15

Python 3 中更简洁的方式:{k.lower(): v for k, v in my_dict.items()}


值方面怎么样? - user3352632
1
{ k.lower(): v.lower() for k, v in my_dict.items() } - user3352632

14
以下内容与Rick Copeland的答案完全相同,只是没有使用生成器表达式:
outdict = {}
for k, v in {'My Key': 'My Value'}.iteritems():
    outdict[k.lower()] = v.lower()

生成器表达式、列表推导式以及(在Python2.7及以上版本)字典推导式基本上是重写循环的方法。

在Python 2.7+版本中,你可以使用字典推导式(它只有一行代码,但你可以重新格式化它们以使其更易读):

{k.lower():v.lower()
    for k, v in
    {'My Key': 'My Value'}.items()
}

使用列表/字典解析通常比使用循环更整洁,因为你不必初始化一个空的dict/list等。但是,如果你需要执行多个函数/方法调用之外的任何操作,它们很快就会变得混乱。


如何将其推广到字典具有超过一个键且每个键有多个值的情况? - user1993

5
这会将字典中所有的键转为小写,即使你有嵌套的字典或列表。你可以类似地执行其他的转换。
def lowercase_keys(obj):
  if isinstance(obj, dict):
    obj = {key.lower(): value for key, value in obj.items()}
    for key, value in obj.items():         
      if isinstance(value, list):
        for idx, item in enumerate(value):
          value[idx] = lowercase_keys(item)
      obj[key] = lowercase_keys(value)
  return obj 

json_str = {"FOO": "BAR", "BAR": 123, "EMB_LIST": [{"FOO": "bar", "Bar": 123}, {"FOO": "bar", "Bar": 123}], "EMB_DICT": {"FOO": "BAR", "BAR": 123, "EMB_LIST": [{"FOO": "bar", "Bar": 123}, {"FOO": "bar", "Bar": 123}]}}

lowercase_keys(json_str)


Out[0]: {'foo': 'BAR',
 'bar': 123,
 'emb_list': [{'foo': 'bar', 'bar': 123}, {'foo': 'bar', 'bar': 123}],
 'emb_dict': {'foo': 'BAR',
  'bar': 123,
  'emb_list': [{'foo': 'bar', 'bar': 123}, {'foo': 'bar', 'bar': 123}]}}

4
我使用 JSON 库首先反序列化字典,然后将其转换为小写,再将其转换回字典。
import json
mydict = {'UPPERCASE': 'camelValue'}
print(mydict)
mydict_in_str = json.dumps(mydict)
mydict_lowercase = json.loads(mydict_in_str.lower())
print(mydict_lowercase)

3
在Python 3中:
d = dict()
d = {k.casefold(): v for k, v in d.items()}

2
如果提供的字典具有多种类型的键/值(数字、字符串等),则请使用以下解决方案。
例如,如果您有一个名为mydict的字典,如下所示:
mydict = {"FName":"John","LName":"Doe",007:true}

在Python 2.x中

dict((k.lower() if isinstance(k, basestring) else k, v.lower() if isinstance(v, basestring) else v) for k,v in mydict.iteritems())

在Python 3.x中

dict((k.lower() if isinstance(k, str) else k, v.lower() if isinstance(v, str) else v) for k,v in mydict.iteritems())

注意:这在单维度字典上运行良好。


此时,我只会创建一个执行检查的小写函数。try_lower = lambda k: k.lower() if isinstance(k, str) else k - Will S

2

由于问题标记了Python,所以回答比较晚。因此,我提供了适用于Python 2.xPython 3.x 的解决方案,并处理了非字符串键的情况。

Python 2.x - 使用字典推导式

{k.lower() if isinstance(k, basestring) else k: v.lower() if isinstance(v, basestring) else v for k,v in yourDict.iteritems()}

演示:

>>> yourDict = {"Domain":"WORKGROUP", "Name": "CA-LTP-JOHN", 111: 'OK', "Is_ADServer": 0, "Is_ConnectionBroker": 0, "Domain_Pingable": 0}
>>> {k.lower() if isinstance(k, basestring) else k: v.lower() if isinstance(v, basestring) else v for k,v in yourDict.iteritems()}
{'domain': 'workgroup', 'name': 'ca-ltp-john', 'is_adserver': 0, 'is_connectionbroker': 0, 111: 'ok', 'domain_pingable': 0}

Python 3.x - Python 3.x 中没有 iteritems()

{k.lower() if isinstance(k, str) else k: v.lower() if isinstance(v, str) else v for k,v in yourDict.items()}

演示:

>>> dict((k.lower() if isinstance(k, basestring) else k, v.lower() if isinstance(v, basestring) else v) for k,v in yourDict.iteritems())
Traceback (most recent call last):
  File "python", line 1, in <module>
AttributeError: 'dict' object has no attribute 'iteritems'
>>> {k.lower() if isinstance(k, str) else k: v.lower() if isinstance(v, str) else v for k,v in yourDict.items()}
>>> {'domain': 'workgroup', 'name': 'ca-ltp-john', 111: 'ok', 'is_adserver': 0, 'is_connectionbroker': 0, 'domain_pingable': 0}

1
在Python 3中,您可以执行以下操作:

dict((k.lower(), v.lower()) for k,v in {'Key':'Value'}.items())

在Python 2中,只需将.iteritems()替换为.items():
dict((k.lower(), v.lower()) for k,v in {'Key':'Value'}.iteritems())

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