Python循环遍历字典以使用来自另一个字典的值替换键

时间:2013-04-02 21:56:42

标签: python loops dictionary

我有一本字典,我想将该字典中的所有键更改为另一个字典中的值。

例如:

X = {"apple" : 42}

Y = {"apple" : "Apples"}

转换后:

Dict X = {"Apples" : 42}

def convert(items, ID):
    for key, value in items.items():
        for keys, values in ID.items():
            if keys == key:
                key = values
    return items

所以我已经编写了上面的代码来执行此操作,但是在执行此功能后,我打印字典并且键没有更改。

6 个答案:

答案 0 :(得分:6)

这是因为您要为局部变量分配新值,而不是为字典键分配新值。

然而,为了获得理想的结果,我建议做其他人已经建议的并创建一个新字典,因为你的密钥与任何现有的字典不对齐:

如果您愿意这样做,则必须通过字典赋值显式设置值:

def convert(X, Y):
    new_dict = {}
    for x_key, x_value in X.items():
        for y_key, y_value in Y.items():
            if x_key == y_key:
                new_dict[y_value] = x_value

    return new_dict

答案 1 :(得分:2)

在第一个循环中,您将迭代(key, value)对。更改key变量的值不会在字典上更新它。

您需要做的是将value重新分配给新的keyvalues)和del旧密钥。此示例创建一个新副本,因此它不会修改dict。我还删除了内部for loop,因为在python中你可以检查密钥是否在dict中,而不是使用if key in dictionary迭代所有密钥。

def convert(items, id):
    new_dict = items.copy()
    for key, value in items.items():
        if key in id:
            new_key = id[key]
            new_dict[new_key] = items[key] # Copy the value
            del new_dict[key]
    return new_dict

示例ipython会话:

In [1]: items = {'apple': 42, 'orange': 17}

In [2]: new_keys = {'apple': 'banana', 'orange': 'tangerine'}

In [3]: def convert(items, ID):
            ...

In [13]: convert(items, new_keys)
Out[13]: {'banana': 42, 'tangerine': 17} # Updated dict returned

In [14]: items
Out[14]: {'apple': 42, 'orange': 17} # Original dict stays untouched

答案 2 :(得分:1)

当您致电items.items()时,您正在创建字典(key, value)对的副本。

因此,当您更改key的值时,您将更改副本的值,而不是原始值。

def convert(items, ID):
    for key, value in items.items():
        for keys, values in ID.items():
            if keys == key:
                items[key] = values
    return items

答案 3 :(得分:1)

您是否有理由需要修改现有字典而不是仅创建新字典?

要通过创建新词典执行相同的任务,请尝试以下操作:

def convert(items, ID):
    result = {}
    for key, value in items.items():
        if key in ID.keys():
            result[ID[key]] = value
        else:
            result[key] = value
    return result

如果你真的想要修改原始字典,你还是要创建一个临时的新字典,然后用新字典的内容填充原文,就像这样

def convert(items, ID):
    result = {}
    for key, value in items.items():
        if key in ID.keys():
            result[ID[key]] = value
        else:
            result[key] = value
    items.clear()
    for key, value in result.items():
        items[key] = value
    return items 

如果你不这样做,那么你必须担心覆盖值,即你试图将密钥重命名为已存在的东西。这是我的意思的一个例子:

items = {"apples": 10, "bananas": 15}
ID = {"apples": "bananas", "bananas": "oranges"}
convert(items, ID)
print items

我认为您想要的行为最终会以{"bananas": 10, "oranges": 15}结束。如果它首先将"apples"重命名为"bananas"怎么办?然后你有{"bananas": 10},然后会成为{"oranges": 10}

最糟糕的是,它完全取决于python迭代键的顺序,这取决于你在第一时间添加它们的顺序。如果这在未来的python版本中发生了变化,那么程序的行为可能会发生变化,这是您绝对想要避免的。

答案 4 :(得分:1)

方法

使用set intersection计算共享密钥。

2.7之前的代码

def convert(items, ID):
    # Find the shared keys
    dst, src = set(items.keys()), set(ID.keys())
    same_keys, diff_keys = dst.intersection(src), dst.difference(src)
    # Make a new dictionary using the shared keys
    new_values = [(ID[key], items[key]) for key in same_keys]
    old_values = [(key, items[key]) for key in diff_keys]
    return dict(new_values + old_values)

代码为2.7 +

def convert(items, ID):
    # Find the shared keys
    dst, src = set(items.keys()), set(ID.keys())
    same_keys, diff_keys = dst.intersection(src), dst.difference(src)
    # Make a new dictionary using the shared keys
    new_values = {ID[key]: items[key] for key in same_keys}
    old_values = {key: items[key] for key in diff_keys}
    return reduce(lambda dst, src: dst.update(src) or dst, [new_values, old_values], {})

测试2.7之前

>>> def convert(items, ID):
...     # Find the shared keys
...     dst, src = set(items.keys()), set(ID.keys())
...     same_keys, diff_keys = dst.intersection(src), dst.difference(src)
...     # Make a new dictionary using the shared keys
...     new_values = [(ID[key], items[key]) for key in same_keys]
...     old_values = [(key, items[key]) for key in diff_keys]
...     return dict(new_values + old_values)
... 
>>> convert({"apple" : 42, "pear": 38}, {"apple" : "Apples", "peach": 31})
{'pear': 38, 'Apples': 42}

测试2.7 +

>>> def convert(items, ID):
...     # Find the shared keys
...     dst, src = set(items.keys()), set(ID.keys())
...     same_keys, diff_keys = dst.intersection(src), dst.difference(src)
...     # Make a new dictionary using the shared keys
...     new_values = {ID[key]: items[key] for key in same_keys}
...     old_values = {key: items[key] for key in diff_keys}
...     return reduce(lambda dst, src: dst.update(src) or dst, [new_values, old_values], {})
... 
>>> convert({"apple" : 42, "pear": 38}, {"apple" : "Apples", "peach": 31})
{'pear': 38, 'Apples': 42}

答案 5 :(得分:0)

问题在于您使用了字典的新本地副本或其键和值

如果问题是返回一个新字典,这将在一行中起作用

def convert(x,y):
    return dict( (y.get(k,k), x[k]) for k in x )
x={'a':10, 'b':5}
y={'a':'A'}
print convert(x,y)

并且在python 2.7+中你甚至可以

def convert(x,y):
     return { y.get(k,k): x[k] for k in x }

但是如果你想在同一个输入字典中工作那么

def convert(x,y):
     r={ y.get(k,k): x[k] for k in x }
     for k in x.keys(): del x[k]
     x.update(r)

x={'a':10, 'b':5}
y={'a':'A'}
convert(x,y)
print x