简体   繁体   English

在python中反转字典

[英]inverting dictionary in python

I have this dictionary 我有这本字典

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

I want the inverse dictionary to be 我想要逆字典

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

I already got the function to inverse but it doesn't look like the second dictionary 我已经将函数反转但它看起来不像第二个字典

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

You can easily do this with collections.defaultdict : 您可以使用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

Your code has two problems 您的代码有两个问题

The first problem you have is at these lines: 你遇到的第一个问题是:

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

When you write movie_dict[actor] = (key) , you are not creating a tuple - the parenthesis are just for precedence. 当你写movie_dict[actor] = (key) ,你没有创建一个元组 - 括号只是用于优先级。 To create a tuple, you would have to add a comma at the end: 要创建元组,您必须在末尾添加逗号:

 movie_dict[actor] = (key,)

Anyway, this will not work as well, because tuples are immutable. 无论如何,这也不会有效,因为元组是不可变的。 You should either use a list: 你应该使用一个列表:

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

or create new tuples: 或创建新元组:

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

I strongly suggest you to use the first option. 我强烈建议你使用第一个选项。 If you really need to use tuples, convert the lists to tuples after the processing. 如果您确实需要使用元组,请在处理后将列表转换为元组。

The second problem is that you seem to expect 第二个问题是你似乎在期待

'rush hour 2'

to be equal to 等于

'rush    hour 2'

as seen in the dictionary: 如字典中所示:

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

But this is not true: 但是这是错误的:

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

How could you solve it? 你怎么能解决它? Well, the simplest solution I devise is to split the string at spaces and then rejoin it with only one space: 好吧,我设计的最简单的解决方案是将字符串拆分为空格,然后只用一个空格重新加入:

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
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
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)
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

Result: 结果:

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

The only problem you have is you're using (key) to represent a list, which should be [key]. 你唯一的问题是你使用(键)来表示一个列表,它应该是[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

There is a very convenient setdefault method in a dict object. dict对象中有一个非常方便的setdefault方法。 With using it, the code simplifies to the following: 使用它时,代码简化为以下内容:

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

A dictionary is by default not not sortable, so you can not sort it. 默认情况下,字典不可排序,因此您无法对其进行排序。 You can look into the structure ordered dictionary if the order matters 如果顺序很重要,您可以查看结构有序字典

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM