在python中反转字典

时间:2011-11-23 17:26:01

标签: python dictionary

我有这本词典

{'jackie chan': ('rush hour', 'rush hour 2'), 
 'crish tucker': ('rush hour', 'rush    hour 2')}

我希望逆字典

{'rush hour': ('jackie chan', 'crish tucker'), 
 'rush hour 2': ('jackie chan', 'crish tucker')}

我已经将函数反转但它看起来不像第二个字典

def invert_actor_dict(actor_dict):
    movie_dict = {}
    for key,value in actor_dict.iteritems():

        for actor in value:
            if actor in movie_dict:
                movie_dict[actor].append(key)
            else:
                movie_dict[actor] = (key)
    return movie_dict

8 个答案:

答案 0 :(得分:5)

您可以使用collections.defaultdict轻松完成此操作:

def invert_dict(d):
    inverted_dict = collections.defaultdict(set)
    for actor, movies in d.iteritems():
        for movie in movies:
            inverted_dict.add(actor)
    return inverted_dict

答案 1 :(得分:4)

您的代码有两个问题

你遇到的第一个问题就在这些方面:

if actor in movie_dict:
    movie_dict[actor].append(key)
else:
    movie_dict[actor] = (key)

当您编写movie_dict[actor] = (key)时,您没有创建元组 - 括号仅用于优先级。要创建元组,您必须在末尾添加逗号:

 movie_dict[actor] = (key,)

无论如何,这也行不通,因为元组是不可变的。你应该使用一个列表:

if actor in movie_dict:
    movie_dict[actor].append(key)
else:
    movie_dict[actor] = [key] # Square brackets

或创建新元组:

if actor in movie_dict:
    movie_dict[actor] = movie_dict[actor] + (key,)
else:
    movie_dict[actor] = (key,)

我强烈建议您使用第一个选项。如果确实需要使用元组,请在处理后将列表转换为元组。

第二个问题是您似乎期待的

'rush hour 2'

等于

'rush    hour 2'

如字典所示:

{'jackie chan': 
    ('rush hour', 'rush hour 2'), 
 'crish tucker': 
    ('rush hour', 'rush    hour 2')}

但事实并非如此:

>>> 'rush hour 2' == 'rush    hour 2'
False

你怎么能解决它?好吧,我设计的最简单的解决方案是将字符串拆分为空格,然后只用一个空格重新加入:

def invert_actor_dict(actor_dict):
    movie_dict = {}
    for key,value in actor_dict.iteritems():
        for actor in value:
            split_movie_name = key.split()
            # 'rush     hour 2'.split() == ['rush', 'hour', '2']
            movie_name = " ".join(split_movie_name)
            # " ".join(['rush', 'hour', '2']) == 'rush hour 2'
            if actor in movie_dict:
                movie_dict[actor].append(movie_name)
            else:
                movie_dict[actor] = [movie_name]
    return movie_dict

答案 2 :(得分:0)

def invert_actor_dict(actor_dict):
   movie_dict = {}
   for actor,movies in actor_dict.iteritems(): 

       for movie in movies:
           if not movie_dict.has(movie):
               movie_dict[movie]=[]
           movie_dict[movie].append(actor)
   return movie_dict

答案 3 :(得分:0)

d = {'jackie chan': ('rush hour', 'rush hour 2'), 'crish tucker': ('rush hour', 'rush hour 2')}
h = dict()

for actor, films in d.items():
    for film in films:
        if not film in h:
            h[film] = list()
        h[film].append(actor)

答案 4 :(得分:0)

d = {'rush hour': ('jackie chan', 'crish tucker'), 'rush hour 2': ('jackie chan', 'crish tucker')}

result = {}

for film, names in d.items():
    for name in names:
        if not name in result:
            result[name] = set([film])
        else:
            result[name].add(film)

print result

<强>结果:

{'crish tucker': set(['rush hour', 'rush hour 2']), 'jackie chan': set(['rush hour', 'rush hour 2'])}

答案 5 :(得分:0)

你遇到的唯一问题是你使用(键)代表一个列表,它应该是[key]。

def invert_actor_dict(actor_dict):
    movie_dict = {}
    for key,value in actor_dict.iteritems():

        for actor in value:
            if actor in movie_dict:
                movie_dict[actor].append(key)
            else:
                movie_dict[actor] = (key)
    return movie_dict

答案 6 :(得分:0)

dict对象中有一个非常方便的setdefault方法。使用它时,代码简化为以下内容:

d = {'rush hour': ('jackie chan', 'crish tucker'), 'rush hour 2': ('jackie chan', 'crish tucker')}

result = {}

for film, names in d.items():
    for name in names:
        result.setdefault(name,set([])).add(film)

print result

答案 7 :(得分:-1)

字典默认情况下不可排序,因此您无法对其进行排序。如果订单重要,您可以查看结构ordered dictionary