2016-04-21 4 views
0

Я работаю над программой, которая принимает текстовый файл imdb, и выводит верхних участников (по видам фильмов) на основе пользовательского ввода N.Объединить элементы в списке кортежей?

Однако я столкнулся с проблемой, у которого есть слоты, занятые актерами в том же количестве фильмов, которые мне нужно избегать. Скорее, если два актера находятся в 5 фильмах, например, должно появиться число 5, и имена актеров должны быть объединены, разделенные точкой с запятой.

Я пробовал много обходных решений, и ничего еще не сработало. Какие-либо предложения?

if __name__ == "__main__": 
    imdb_file = raw_input("Enter the name of the IMDB file ==> ").strip() 
    print imdb_file 
    N= input('Enter the number of top individuals ==> ') 
    print N 


    actors_to_movies = {} 

    for line in open(imdb_file): 
     words = line.strip().split('|') 
     actor = words[0].strip() 
     movie = words[1].strip() 
     if not actor in actors_to_movies: 
      actors_to_movies[actor] = set() 
     actors_to_movies[actor].add(movie) 

    movie_list= sorted(list(actors_to_movies[actor])) 

    #Arranges Dictionary into List of Tuples# 
    D = [ (x, actors_to_movies[x]) for x in actors_to_movies] 
    descending = sorted(D, key = lambda x: len(x[1]), reverse=True) 

    #Prints Tuples in Descending Order N number of times (User Input)# 
    for i in range(N): 
     print str(len(descending[i][1]))+':', descending[i][0] 
+0

Имея весь код вложен в 'если __name__ ==«__main __»:' означает, что ни одна из его функциональных возможностей не будет доступна, если файл будет импортирован другим сценарием. – jDo

ответ

3

Существует полезный метод itertools.groupby

Это позволяет разделить список на группы по какому-либо ключу. С его помощью вы можете легко написать функцию, которая выводит ведущих актеров:

import itertools 
def print_top_actors(actor_info_list, top=5): 
    """ 
    :param: actor_info_list should contain tuples of (actor_name, movie_count) 
    """ 
    actor_info_list.sort(key=lambda x: x[1], reverse=True) 
    for i, (movie_count, actor_iter) in enumerate(itertools.groupby(actor_info_list)): 
     if i >= top: 
      break 
     print movie_count, ';'.join(actor for actor, movie_count in actor_iter) 

и пример использования:

>>> print_top_actors(
...  [ 
...   ("DiCaprio", 100500), 
...   ("Pitt", 100500), 
...   ("foo", 10), 
...   ("bar", 10), 
...   ("baz", 10), 
...   ("qux", 3), 
...   ("lol", 1) 
...  ], top = 3) 
100500 DiCaprio;Pitt 
10 foo;bar;baz 
3 qux 
+0

Пара вещей: вы вызываете top_Actors в примере, даже если вы определили print_top_actors, вы также говорите, что в вашем комментарии actor_info_list порядок tuple должен быть movie_count, имя актера, но в примере имя актера наступает сначала, а затем отсчет фильма. Выполнение кода as возвращает список в стиле: (Actorname, moviecount) actorname и не объединяет имена актеров вообще для меня. –

+0

Мне очень жаль. Исправлен пример и комментарий. Правильный способ вызова - как в примере, хотя вы всегда можете его изменить, вам просто нужно изменить 'key' в' sort'/'groupby' –

Смежные вопросы