добавлен дополнительный словарный ключ для цикла for - PullRequest
0 голосов
/ 29 января 2019

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

Вот исходный вызов функции:

    movies = {"How to Be Single": ["Alison Brie", "Dakota Johnson",
                               "Rebel Wilson"],
              "The Lego Movie": ["Will Arnett", "Elizabeth Banks",
                             "Alison Brie", "Will Ferrell"]}
    print(stars,movies)

Вот код:

def stars(movies):
# create a new dictionary
films_dict= {}
performances_films = []

# for each movie actor, add as key to new_dict
for movie, actors in movies.items():
    for actor in actors:
        if not actor in films_dict.keys():
            #print(actor)
            performances_films = []
            performances_films.append(movie)
            films_dict[actor] = performances_films
        else:
            performances_films.append(movie)
            films_dict[actor] = performances_films

return(films_dict)

Здесьэто вывод:

RUN 1
    {'Rebel Wilson': ['How to Be Single'], 'Will Ferrell': ['The Lego 
    Movie'], 
    'Will Arnett': ['The Lego Movie'], 'Elizabeth Banks': ['The Lego Movie', 
    'The Lego Movie'], 'Alison Brie': ['The Lego Movie', 'The Lego Movie'], 
    'Dakota Johnson': ['How to Be Single']}

RUN 2
{'Will Arnett': ['The Lego Movie'], 'Dakota Johnson': ['How to Be Single'], 'Elizabeth Banks': ['The Lego Movie', 'The Lego Movie'], 'Rebel Wilson': ['How to Be Single'], 'Will Ferrell': ['The Lego Movie'], 'Alison Brie': ['The Lego Movie', 'The Lego Movie']}

Я думаю, что это либо итерация элементов dict в разном порядке при каждом запуске, либо сохранение данных из одного цикла в другой.В любом случае я не могу решить это.

Ответы [ 3 ]

0 голосов
/ 29 января 2019
movies = {"How to Be Single": ["Alison Brie", "Dakota Johnson",
                               "Rebel Wilson"],
              "The Lego Movie": ["Will Arnett", "Elizabeth Banks",
                             "Alison Brie", "Will Ferrell"]}
stars = {}
for movie, v in movies.items():
    for star in v:
        if star in stars:
            stars[star].append(movie)
        else:
            stars[star] = [movie]

print(stars)

отпечатков:

{'Alison Brie': ['How to Be Single', 'The Lego Movie'], 'Dakota Johnson': ['How to Be Single'], 'Rebel Wilson': ['How to Be Single'], 'Will Arnett': ['The Lego Movie'], 'Elizabeth Banks': ['The Lego Movie'], 'Will Ferrell': ['The Lego Movie']}
0 голосов
/ 29 января 2019

Ошибка в вашем коде в том, что экземпляр list performances_films сохраняется от одной итерации цикла к следующей.Вот почему (скажем) у Элисон Бри дважды упоминался фильм «Лего» - его действительно предполагалось добавить для другого актера, но экземпляр list, ранее созданный для Элисон Бри, все еще занимал слот имени performances_films.На самом деле, похоже, что несколько актеров могут совместно использовать один и тот же list экземпляр.

Вы можете значительно упростить код, если при обращении к словарю используете концепцию "значение по умолчанию".Это можно сделать, используя класс collections.defaultdict:

import collections
filmography = collections.defaultdict(list)
for movie, actors in movies.items():
    for actor in actors:
        filmography[actor].append(movie)

, или я бы предпочел использовать ваниль dict и setdefault()Метод:

filmography = {}                     
for movie, actors in movies.items():
    for actor in actors:
        filmography.setdefault(actor, []).append(movie)

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

.
0 голосов
/ 29 января 2019

Я не совсем понимаю, почему вы держите список performances_films.Вы можете просто использовать те, которые вы создали ранее, в самом dict.

Вот что, я думаю, будет работать:

def stars(movies):
    # create a new dictionary
    films_dict= {}

    # for each movie actor, add as key to new_dict
    for movie, actors in movies.items():
        for actor in actors:
            if not actor in films_dict.keys():
                performances_films = []
                performances_films.append(movie)
                films_dict[actor] = performances_films
            else:
                films_dict[actor].append(movie)

    return(films_dict)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...