在Python中交换字典中的键和值

80

假设我有一个这样的字典:

my_dict = {2:3, 5:6, 8:9}

有没有一种方法可以交换键和值,得到以下结果:
{3:2, 6:5, 9:8}

2
这些值是唯一的吗?这些值是可哈希的吗? - wim
2
my_new_dict = dict(zip(my_dict.values(), my_dict.keys())) 这个怎么样? - nauer
10个回答

127

对于Python 3:

my_dict2 = {y: x for x, y in my_dict.items()}

对于Python 2,您可以使用:

my_dict2 = dict((y, x) for x, y in my_dict.iteritems())

8
.iteritems() 在 Python 3.x 上无效。 - JBernardo
3
另一个修正 - 进行你建议的字典解析 {(y, x) for x, y in dic_cols_w.items()} 会返回一个集合,而不是一个字典。你仍需要将其包装在 dict(...) 中才能获得一个字典。 - tsando
4
@tsando:我认为你误读了我的回答。我的意思是{y:x ... - GWW
我不确定我理解了。也许可以提出一个新问题或寻找另一个答案? - GWW
1
对于未来的读者:对于Python 3.x,请使用item()而不是iteritems(),即my_dict2 = {y:x for x,y in my_dict.items()}。来源:https://dev59.com/iHRB5IYBdhLWcg3w3K8J#483833 - Milan
显示剩余3条评论

14
my_dict = { my_dict[k]:k for k in my_dict}

3
请问您需要翻译的原文是什么? - gosuto

9

试试这个:

my_dict = {2:3, 5:6, 8:9}

new_dict = {}
for k, v in my_dict.items():
    new_dict[v] = k

7

使用这个代码(稍作修改)来自Python反转/倒置映射的被接受答案:

dict((v,k) for k, v in my_dict.iteritems())

请注意,这假定原始字典中的值是唯一的。否则,您将在生成的字典中得到重复的键,这是不允许的。
另外,正如@wim指出的那样,它还假定值是可哈希的。如果您不确定什么是可哈希的,请参阅Python词汇表

6
也许可以这样理解:
flipped_dict = dict(zip(my_dict.values(), my_dict.keys()))
是将一个字典中的键和值翻转,生成一个新的字典。

2
这可能不是很安全,因为它依赖于键和值的顺序,尽管对我来说它起作用了。我喜欢JBernardo/GWW的答案。 - aaron
最好使用iterkeysitervalues - GWW
如果在操作过程中字典没有被改变,那就是安全的。我喜欢你不使用理解就完成了它。 - JBernardo

3
首先,这并不是一定能做到的,因为字典的值可能是不可哈希的。
如果字典的值是不可哈希的,可以使用函数式方法:
reversed_dict = dict(map(reversed, original_dict.items()))

2
有时候,数值不唯一的条件可能无法满足,这种情况下,上述答案会删除任何重复的数值。
以下将可能重复的数值滚动到列表中:
from itertools import count
dict([(a,[list(d.keys())[i] for i,j in zip(count(), d.values())if j==a in set(d.values())])

我相信有更好的方法(非列表推导式),但是之前的答案存在问题,所以我提供了我的解决方案,以防其他人有类似的用例。

附注:不要期望在原始字典更改后,字典保持整齐!这种方法只能在静态字典上使用一次 - 你已经被警告了!


2
如果值不唯一,这将在转换中导致键空间冲突。最好在交换位置时将键保留在列表中。
以下处理此操作 -
RvsD = dict()
for k,v in MyDict.iteritems():
    RsvD.setdefault(v, []).append(k)

1
如果字典中的值不是唯一的,则可以将键映射到该值。以下是使用defaultdict执行此操作的示例。
from collections import defaultdict


def reverse_dict(data: dict) -> dict:
    rd = defaultdict(list)
    for k, v in data.items():
        rd[v].append(k)
    return rd


if __name__ == "__main__":
    from collections import Counter

    data = "aaa bbb ccc ddd aaa bbb ccc aaa"
    c = Counter(data.split())
    print(c)
    # Counter({'aaa': 3, 'bbb': 2, 'ccc': 2, 'ddd': 1})
    rd = reverse_dict(c)
    print(rd)
    # defaultdict(<class 'list'>, {3: ['aaa'], 2: ['bbb', 'ccc'], 1: ['ddd']})

1

您可以这样做:

功能:

def inverse_dict(my_dict):
    updated_dict = {}
  
    for i in my_dict:
        updated_dict[my_dict[i]] = [i]

    return updated_dict

Main():

def main():
    year = {'day': 15, 'month': 3, 'year': 2019}
    print(inverse_dict(year))

if __name__ == "__main__":
    main()

输出:
{15: ['day'], 3: ['month'], 2019: ['year']}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接