2013-05-02 44 views
0

以下字典的作品,但不是OrderedDict。对于od来说,它似乎形成了一个无限循环。你能告诉我为什么吗? 如果函数输入是字典它必须返回字典,如果输入是OrderedDict它必须返回od。更改键为小写字母或OrderedDict

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 

回答

2

它形成的原因有序字典添加新成员(为末)

由于您使用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

+0

我以为是一旦我创建了它设置的发生器。谢谢你澄清这一点。 但我不想创建一个新的字典,我想保持相同类型的字典/ orderedDict没有测试他们的类型,因此保持相同的字典。 在这种情况下,应该使用d.keys()而不是d.iterkeys()。 – 2013-05-02 17:10:33

+0

但为什么它为字典工作?生成器在添加时仍应继续生成密钥,并创建无限循环。 – 2013-05-02 17:25:02

+0

在大小写不变的情况下,在大写和小写之间切换可将钥匙保持在相同的位置。所以,简单地将'ONE'换成'one'作为关键字将取代相同索引处的关键字。 OrderedDict将始终追加键/值。使用d.keys()工作的 – sberry 2013-05-02 17:33:06

0

如前所述sberry,无限循环基本上如要修改,并在同一时间阅读的字典。

也许最简单的解决方案是使用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 

的键在开始直接拍下,他们将不会得到项目在字典改变更新。

+0

。谢谢。 我想用d.iterkeys()来节省一些时间。 – 2013-05-02 17:26:42

相关问题