在Python中实现字典反转

5

我有这个字典

{'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
克里斯·塔克(Chris Tucker)可能会对你拼错他的名字有意见。 - Zeke
1
你是如何拼写第二部电影的?或者你想要额外的空格被删除吗? - wal-o-mat
8个回答

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

4
你的代码存在两个问题。
第一个问题出现在以下几行代码:
```html (以下是原始代码) ```
第二个问题需要检查整个代码。
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

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

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)

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'])}

0
你唯一的问题是你正在使用(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

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

-1

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


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