【问题标题】:change key to lower case for dict or OrderedDict将 dict 或 OrderedDict 的键更改为小写
【发布时间】:2013-05-02 16:36:51
【问题描述】:

以下适用于字典,但不适用于 OrderedDict。对于 od 它似乎形成了一个无限循环。你能告诉我为什么吗? 如果函数输入是dict它必须返回dict,如果输入是OrderedDict它必须返回od。

def key_lower(d):
    """returns d for d or od for od with keys changed to lower case
    """
    for k in d.iterkeys():
        v = d.pop(k)
        if (type(k) == str) and (not k.islower()):
            k = k.lower()
        d[k] = v

    return d

【问题讨论】:

    标签: python dictionary ordereddictionary


    【解决方案1】:

    由于有序字典添加新成员的方式(到最后),它形成了一个无限循环

    由于您使用的是iterkeys,它使用的是生成器。当您分配 d[k] = v 时,您将新的键/值添加到字典的末尾。因为您使用的是生成器,所以在您继续添加密钥时,它将继续生成密钥。

    您可以通过几种方式解决此问题。一种是从之前创建一个新的有序字典。

    def key_lower(d):
         newDict = OrderedDict()
        for k, v in d.iteritems():
            if (isinstance(k, (str, basestring))):
                k = k.lower()
            newDict[k] = v
        return newDict
    

    另一种方法是不使用生成器并使用keys 而不是iterkeys

    【讨论】:

    • 我想的是,一旦我创建了它被设置的生成器。谢谢你澄清这一点。但我不想创建一个新的字典,我想保持相同类型的字典/orderedDict 而不测试它们的类型,因此保持相同的字典。在这种情况下,使用 d.keys() 而不是 d.iterkeys() 应该可以工作。
    • 但为什么它对 dict 有效?生成器在添加密钥后仍应继续生成密钥,并创建无限循环。
    • 在大写和小写之间切换使键保持在相同的位置,前提是字典的大小没有改变。因此,简单地将 'ONE' 与 'one' 交换为键将替换同一索引处的键。 OrderedDict 将始终附加键/值。
    【解决方案2】:

    正如 sberry 所提到的,无限循环本质上是在您同时修改和读取 dict 时。

    可能最简单的解决方案是使用OrderedDict.keys() 而不是OrderedDict.iterkeys()

    for k in d.keys():
        v = d.pop(k)
        if (type(k) == str) and (not k.islower()):
            k = k.lower()
        d[k] = v
    

    由于键是在开始时直接捕获的,因此它们不会随着字典中的项目的更改而更新。

    【讨论】:

    • 使用 d.keys() 有效。谢谢你。我想使用 d.iterkeys() 来节省一些时间。
    猜你喜欢
    • 2019-01-19
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    • 2010-09-25
    • 2014-09-23
    • 2012-03-08
    • 1970-01-01
    相关资源
    最近更新 更多