优雅的Python解决方案:强制嵌套Unicode字符串字典中所有键和值为小写?

5 投票
6 回答
3663 浏览
提问于 2025-04-15 11:24

我很好奇这里的Python高手们会如何优雅地、符合Python风格地完成以下任务:

我有一个数据结构,它是一个字典,里面的键是Unicode字符串,值是另一个字典,这个字典的键也是Unicode字符串,值是Unicode字符串的列表。所以:

>>> type(myDict)
<type 'dict'>
>>> type(myDict[u'myKey'])
<type 'dict'>
>>> type(myDict[u'myKey'][u'myKey2'])
<type 'list'>
>>> type(myDict[u'myKey'][u'myKey2'][0])
<type 'unicode'>

我想把里面的每个字符串都变成小写,也就是说,所有的键和每个列表中的每个字符串都要变成小写。

你们会怎么做呢?

6 个回答

1

以下内容适用于你的示例输入:

>>> myDict = {'myKey': {'myKey2': [u'Abc']}}
>>> newDict = dict([
        (k1.lower(), dict([
            (k2.lower(), [x.lower() for x in myDict[k1][k2]])
                for k2 in myDict[k1].keys()
        ])) for k1 in myDict.keys()
    ])
>>> newDict
{'mykey': {'mykey2': [u'abc']}}
4

一个递归的变体:

def make_lowercase(obj):
    if hasattr(obj,'iteritems'):
        # dictionary
        ret = {}
        for k,v in obj.iteritems():
            ret[make_lowercase(k)] = make_lowercase(v)
        return ret
    elif isinstance(obj,basestring):
        # string
        return obj.lower()
    elif hasattr(obj,'__iter__'):
        # list (or the like)
        ret = []
        for item in obj:
            ret.append(make_lowercase(item))
        return ret
    else:
        # anything else
        return obj

示例:

>>> make_lowercase({'Foo': [{1: 'Baz', 'Bar': 2}]})
{'foo': [{1: 'baz', 'bar': 2}]}
23

这是一种非常简单的方法,不过我不太确定这算不算是“Python风格”:

newDict = eval(repr(myDict).lower())

更合理的方法:

newDict = dict((k1.lower(),
                dict((k2.lower(),
                      [s.lower() for s in v2]) for k2, v2 in v1.iteritems()))
               for k1, v1 in myDict.iteritems())

撰写回答