В словаре найдите ключи с наибольшим количеством общих значений - PullRequest
0 голосов
/ 21 июня 2019

Я не знаю, с чего начать. Были даны следующие инструкции:

Найдите актеров, у которых больше всего фильмов. Выведите все связи. Решение использует словарь name_and_movies, который связывает каждого человека с набором фильмов, в которых он / она участвует. Тогда вам понадобится удвоить число циклов. Это может быть сделано быстрее с помощью интеллектуально завершающих циклов. Если найдены актеры с общим количеством k фильмов, вам не нужно рассматривать актеров с менее чем k фильмами.

Это словарь name_and_movies.

{'Kishiro, Yukito': {'Battle Angel'}, 
'Wilson, Owen': {'The Internship', 
'Midnight in Paris', 'Wedding Crashers'}, 
'Vaughn, Vince': {'Made', 'Swingers', 
'The Internship', 'Wedding Crashers'}, 
'Favreau, Jon': {'Made', 'Swingers'}, 
'Jackman, Hugh': {'The Greatest Showman', 'X-Men'}, 
'Roth, Tim': {'Planet of the Apes'}, 
'Cooper, Chris': {'Capote'}, 
'Wilson, Luke': {'Rushmore'}, 
'Vaughn, Robert': {'The Statue'}, 
'Graham, Heather': {'Swingers'}}

Ожидаемый результат:

У Винса Вона и Оуэна Уилсона есть 2 общих фильма.

У Винса Вона и Джона Фавро есть 2 общих фильма.

1 Ответ

0 голосов
/ 21 июня 2019

Вы можете использовать комбинации () из itertools для генерации пар актеров и пересечения их фильмов. Затем выберите пары с наибольшим пересечением:

films = {'Kishiro, Yukito': {'Battle Angel'}, 
'Wilson, Owen': {'The Internship', 
'Midnight in Paris', 'Wedding Crashers'}, 
'Vaughn, Vince': {'Made', 'Swingers', 
'The Internship', 'Wedding Crashers'}, 
'Favreau, Jon': {'Made', 'Swingers'}, 
'Jackman, Hugh': {'The Greatest Showman', 'X-Men'}, 
'Roth, Tim': {'Planet of the Apes'}, 
'Cooper, Chris': {'Capote'}, 
'Wilson, Luke': {'Rushmore'}, 
'Vaughn, Robert': {'The Statue'}, 
'Graham, Heather': {'Swingers'}}


from itertools import combinations
common    = [ (a1,a2,films[a1]&films[a2]) for a1,a2 in combinations(films,2) ]
maxCommon = max(len(c[2]) for c in common)
result    = [ (actor1,actor2) for actor1,actor2,films in common if len(films)==maxCommon ]
print(maxCommon,result)

# 2 [('Wilson, Owen', 'Vaughn, Vince'), ('Vaughn, Vince', 'Favreau, Jon')]

Примечание. Выходные данные в парах, поэтому он не предполагает, что у Оуэна Уилсона есть 2 общих фильма с Джоном Фавро.

Вы можете добавить пересечение фильмов, чтобы узнать, какие фильмы являются общими для актеров:

result    = [ (actor1,actor2,films) for actor1,actor2,films in common if len(films)==maxCommon ]

# 2 [('Wilson, Owen', 'Vaughn, Vince', {'Wedding Crashers', 'The Internship'}), ('Vaughn, Vince', 'Favreau, Jon', {'Swingers', 'Made'})]

EDIT Без использования списочных представлений (то есть с использованием циклов) это то, что соответствует:

common    = list()
maxCommon = 0
actors    = list(films)
for i,actor1 in enumerate(actors[:-1]):
    for actor2 in actors[i+1:]:
        commonFilms = films[actor1] & films[actor2]
        common.append( (actor1,actor2,commonFilms) )
        maxCommon = max(len(commonFilms),maxCommon)
result = list()
for actor1,actor2,films in common:
    if len(films)==maxCommon:
        result.append((actor1,actor2))
print(maxCommon,result)
...