мне нужно объединить 2 словаря в один(каждый создается из csv файла в двух функциях)
надо закинуть возвращаемые значения двух первых функций в 3 и объединить их. понимаю, что решение где-то на поверхности, но никак не могу понять, как это сделать аккуратно и красиво. буду рад любой помощи, заранее спасибо этот код без 3 функции с объединением
result: {1: 3.5, 2: 4.67}
lst_movie:
[{'movieId': 1, 'year': '2018', 'title': 'Bungo Stray Dogs: Dead Apple (2018)', 'genres': 'Action|Animation', 'rating': None},
{'movieId': 2, 'year': '1991', 'title': 'Andrew Dice Clay: Dice Rules (1991)', 'genres': 'Comedy', 'rating': None}]
в result закидываю значения по такой схеме {movieId: rating} и на место rating в lst_movie(который None) нужно поставить rating из result в соответствии с movieId. если в result нет rating к какому-то movieId, то остается None
import csv
import re
from collections import defaultdict as df
def csv_movie(file_obj):
reader = csv.reader(file_obj)
next(f_obj)
lst_movie = []
for row in reader:
dic = dict()
dic['movieId'] = int(row[0])
dic['year'] = ''.join(re.findall('(?<=\()[0-9]{4}(?=\))', row[1]))
dic['title'] = row[1]
dic['genres'] = row[2]
dic['rating'] = None
lst_movie.append(dic)
return lst_movie
def csv_rating(file):
reader = csv.reader(file)
lst = []
next(obj) # 8 строка
for row in reader:
dic = dict()
dic[int(row[1])] = float(row[2])
lst.append(dic)
d = df(list)
for i in lst:
for j in i.keys():
d[j].append(i[j])
result = {k: round(sum(v) / len(v), 2) for k, v in d.items()}
return result
if __name__ == "__main__":
csv_movies = "movies.csv"
csv_ratings = "ratings.csv"
with open(csv_movies, "r") as f_obj:
csv_movie(f_obj)
with open(csv_ratings, "r") as obj:
csv_rating(obj)
UPD
добавил как вы посоветовали
def fill_movie_rating(lst_movie, result):
for movie in lst_movie:
movie['rating'] = result.get(movie['movieId'])
print(lst_movie)
if __name__ == "__main__":
csv_movies = "movies.csv"
csv_ratings = "ratings0.csv"
with open(csv_movies, "r") as f_obj:
csv_movie(f_obj)
lst_movie = csv_movie(f_obj) # 48 строка
with open(csv_ratings, "r") as obj:
csv_rating(obj)
result = csv_rating(obj)
выдало ошибку:
Traceback (most recent call last):
line 48, in <module>
lst_movie = csv_movie(f_obj)
line 8, in csv_movie
next(f_obj)
StopIteration
если удалить из main, то ничего не выводится
Ответы (2 шт):
В результате исполнения двух вышеописанных функции вы имеете двe переменных. Одна из них lst_movie (тип list), которая содержит общие данные о фильмах и вторая result (тип dict), в котором хранятся рейтинги фильмов.
Входные данные, которые будут использованы:
lst_movie = [{'movieId': 193587, 'year': '2018', 'title': 'Bungo Stray Dogs: Dead Apple (2018)', 'genres': 'Action|Animation', 'rating': None}, {'movieId': 193609, 'year': '1991', 'title': 'Andrew Dice Clay: Dice Rules (1991)', 'genres': 'Comedy', 'rating': None}]
result = {193587: 3.5, 2: 4.67, 3: 4.33}
что будем делать? Брать значение movieId из result (который есть ключ), искать его в lst_movie и определять рейтинг, который соответствует movieId
>>> for i in result:
... for k in lst_movie:
... if i == k["movieId"]:
... k["rating"] = result[i]
И в итоге имеем:
>>> print(lst_movie)
[{'movieId': 193587, 'year': '2018', 'title': 'Bungo Stray Dogs: Dead Apple (2018)', 'genres': 'Action|Animation', 'rating': 3.5}, {'movieId': 193609, 'year': '1991', 'title': 'Andrew Dice Clay: Dice Rules (1991)', 'genres': 'Comedy', 'rating': None}]
т.е. рейтинг фильма с 'movieId': 193587 изменился на 3.5
UPD сама функция
def union_dict(result:dict, lst_movie:list) -> list:
for i in result:
for k in lst_movie:
if i == k["movieId"]:
k["rating"] = result[i]
return lst_movie
вызов
union_dict(result, lst_movie)
Я бы так же обратил внимание на ответ от @CrazyElf. Он объективно лучше
Если в result точно есть все movieId из lst_movie, то можно так:
def fill_movie_rating(lst_movie, result):
for movie in lst_movie:
movie['rating'] = result[movie['movieId']]
А если там есть не все movieId, то нужно делать через get, чтобы не выпало исключение:
def fill_movie_rating(lst_movie, result):
for movie in lst_movie:
movie['rating'] = result.get(movie['movieId'])