1

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

例如:

X = {"apple" : 42}

Y = {"apple" : "Apples"}

转换后:

字典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

所以我写了上面的代码来做到这一点,但是在执行这个函数之后,我打印了字典并且键没有改变。

4

6 回答 6

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
于 2013-04-02T22:01:46.533 回答
2

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

相反,您需要做的是将 重新分配value给新的key( values) 和del旧的键。此示例创建一个新副本,因此它不会就地修改 dict。我还删除了 inner 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
于 2013-04-02T22:02:05.600 回答
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
于 2013-04-02T22:04:35.093 回答
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 版本中发生了变化,那么你的程序的行为可能会改变,这是你绝对想要避免的。

于 2013-04-02T22:09:30.730 回答
1

方法

使用集合交集计算共享密钥。

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}
于 2013-04-02T22:24:49.363 回答
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
于 2013-04-03T19:39:35.333 回答