Python Forum
Creating a list of dictionaries while iterating
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Creating a list of dictionaries while iterating
#1
Hi everyone,

The class I'm writing queries TMDB and, for now, writes data to a txt file. I've written a method to populate global variables to use later but I need a way to organize the same type of data for multiple people in a single list. ie. Dictionaries inside a list.

Below is the piece of code that I'm struggling with. The method populates an existing list with specific pieces of information to use in other tasks later. What I want to do create dictionaries named j['name'] inside list director_known_for and add the rest of the existing .append statement as the value of an increasing key series =. ie. inc=1 movie[inc] inc +=1 incrementing.

Desired data structure:
director_known_for = [director1: {movie1:{k['title'] + " " + k['release_date'] + " " + "https://www.themoviedb.org/movie/" + str(k['id'])}, 
                                 movie2:k['title'] + " " + k['release_date'] + " " + "https://www.themoviedb.org/movie/" + str(k['id'])}, 
                      director2:{movie1:k['title'] + " " + k['release_date'] + " " + "https://www.themoviedb.org/movie/" + str(k['id'])}, 
				                 movie2:k['title'] + " " + k['release_date'] + " " + "https://www.themoviedb.org/movie/" + str(k['id'])},  
Sorry if my dict formatting is a little off. This is the first time I'm trying to write to/create dictionaries :)

*NOTE* I kept the indentation as-is from the code because this is a block inside a class method.
director_known_for = []
        if bool(self.director_known_for):    # Add organization and output for multiple directors. maybe a list containing dicts?
            for i in directors:
                director_search = search.person(query=i)
                for j in director_search['results']:
                    for k in  j['known_for']:
                        director_known_for.append(j['name'] + " " + k['title'] + " " + k['release_date'] + " " + "https://www.themoviedb.org/movie/" + str(k['id']))
Any help is greatly appreciated!
Reply
#2
Let's figure out the structure you want. The "director_known_for" bit is right now a list, with odd elements. Maybe instead of a list you want another dict, so you can index by director? Then those values will be another dict? Is the stuff after "director1" supposed to be the value? If so, then (with some f-string reformatting), maybe this is what you're looking for?

tmdb_url = "https://themoviedb.org/movie"
director_known_for = {
                       director1: {movie1: f"{k['title']} {k['release_date']} {tmdb_url} {k['id']}",
                                   movie1: f"{k['title']} {k['release_date']} {tmdb_url} {k['id']}",
                                  },
                     }
Why are the elements like k['title'] used repeatedly? Since k isn't changing, this will be the same in all the items.
Reply
#3
The fstring formatting makes sense. I hadn't quite wrapped my head around it yet. Thanks for that.

I see 2 acceptable ways to achieve the desired results and I would like to understand both.

1. Your method is totally acceptable and I want to understand how to achieve it.
2. Nesting a list of strings inside dicts. director1 would be the key (using the actual director's name) and the value would be the list of fstrings.
director_known_for = {
                       director1: [f"{k['title']} {k['release_date']} {tmdb_url} {k['id']}",
                                   {f"{k['title']} {k['release_date']} {tmdb_url} {k['id']}",
                                  ],
                     }
As far as the repeated elements... how would I write the statements without the reference to the object? Maybe seeing the entire script will be more helpful. I'm sure there are a million things wrong or that could be improved, but it's my first try writing a class. I did not include your suggestions yet but will after I understand the issue at hand. I was going to post the script fairly soon to ask for suggested improvements anyway.

import tmdbsimple as tmdb

tmdb.API_KEY = 'REMOVED'

txt_file = "C:\\Users\\REMOVED\\python_apps\\my_progs\\test_folder\\test\\test.txt"
moviename = "The Directive"
tmdb_id = 589187
movie_query = tmdb.Movies(tmdb_id)
search = tmdb.Search()
response = search.movie(query=moviename)
keywords_query = movie_query.keywords()
credits_query = movie_query.credits()
release_dates_query = movie_query.release_dates()
recommendations_query = movie_query.recommendations()
similar_query = movie_query.similar_movies()

keywords = []
actors = []
directors = []
writers = []
release_dates = []
recommendations = []
similar_movies = []
director_known_for = []
writers_known_for = []
director_known_for1 = []
#writers_known_for1 = []

class tmdb_data:
    def __init__(self, *, keyword: bool = True, actors: bool = True, director: bool = True, writer: bool = True, release_dates: bool = True, recommendations: bool = True, similar_movies: bool = True, director_known_for: bool = True, writer_known_for: bool = True):
        self.keyword = keyword
        self.actors = actors
        self.director = director
        self.writer = writer
        self.release_dates = release_dates
        self.recommendations = recommendations
        self.similar_movies = similar_movies
        self.director_known_for = director_known_for
        self.writer_known_for = writer_known_for

    def populate_movie_objs(self):
        if bool(self.keyword):
            for kw in keywords_query['keywords']:
                keywords.append(kw['name'])
        if bool(self.actors):
            for actor in credits_query['cast']:
                if 'cast_id' in actor:
                    actors.append(actor['name'])
        if bool(self.director):
            for crew in credits_query['crew']:
                if 'credit_id' in crew:
                    if "Directing" in crew['department']:
                        directors.append(crew['name'])
        if bool(self.writer):
            for crew in credits_query['crew']:
                if 'credit_id' in crew:
                    if "Writing" in crew['department']:
                        writers.append(crew['name'])
        if bool(self.release_dates):
            for i in release_dates_query['results']:
                for j in i['release_dates']:
                    long_date = j['release_date']
                for k in i:
                    if k == 'iso_3166_1':
                        release_dates.append(i['iso_3166_1'] + " " + long_date[0:10])
        if bool(self.recommendations):
            for i in recommendations_query['results']:
                recommendations.append(i['title'] + " " + i['release_date'] + " " + "https://www.themoviedb.org/movie/" + str(i['id']))
            sim_inc = 1
        if bool(self.similar_movies):
            for i in similar_query['results']:
                similar_movies.append(i['title'] + " " + i['release_date'] + " " + "https://www.themoviedb.org/movie/" + str(i['id']))
                sim_inc += 1
                if sim_inc > 5:
                    break
        if bool(self.director_known_for):    # Add organization and output for multiple directors. maybe a list containing dicts?
            for i in directors:
                director_search = search.person(query=i)
                inc = 0
                for j in director_search['results']:
                    for k in  j['known_for']:
                        director_known_for.append(j['name'] + " " + k['title'] + " " + k['release_date'] + " " + "https://www.themoviedb.org/movie/" + str(k['id']))
        if bool(self.writer_known_for):
            for i in writers:
                if i in directors:
                    print(i + " is a duplicate of Director. Not writing including in Writer output.")
                else:
                    writer_search = search.person(query=i)
                    for j in writer_search['results']:
                        for k in j['known_for']:
                            writers_known_for.append(j['name'] + " " + k['title'] + " " + k['release_date'] + " " + "https://www.themoviedb.org/movie/" + str(k['id']))

    def write_to_txt(self):
        with open(txt_file, "a") as txt:
            if bool(self.keyword):
                txt.write("[size=4][b][u]Keywords[/u][/b][/size]\n")
                for i in keywords:
                    txt.write(i + ", ")
                txt.write("\n")
                txt.write("\n")
            if bool(self.actors):
                txt.write("[size=4][b][u]Actors[/u][/b][/size]\n")
                for i in actors:
                    txt.write(i + "\n")
                txt.write("\n")
            if bool(self.director):
                txt.write("[size=4][b][u]Directors[/u][/b][/size]\n")
                for i in directors:
                    txt.write(i + "\n")
                txt.write("\n")
            if bool(self.release_dates):
                txt.write("[size=4][b][u]Release Dates[/u][/b][/size]\n")
                for i in release_dates:
                    txt.write(i + " \n")
                txt.write("\n")
            if bool(self.recommendations):
                txt.write("[size=4][b][u]Movies Recommendations from TMDB[/u][/b][/size]\n")
                for i in recommendations:
                    txt.write(i + "\n")
                txt.write("\n")
            if bool(self.similar_movies):
                txt.write("[size=4][b][u]Similar Movies[/u][/b][/size]\n")
                for i in similar_movies:
                    txt.write(i + "\n")
                txt.write("\n")
            if bool(self.director_known_for):
                txt.write("[size=4][b][u]Director(s) Known For[/u][/b][/size]\n")
                for i in director_known_for:
                    txt.write(i + "\n")
                txt.write("\n")
            if bool(self.writer_known_for):
                txt.write("[size=4][b][u]Writer(s) Known for[/u][/b][/size]\n")
                for i in writers_known_for:
                    txt.write(i + "\n")
                txt.write("\n")

info_selector = tmdb_data(keyword=True, actors=True, director=True, writer=True, release_dates=True, recommendations=True, similar_movies=True, director_known_for=True, writer_known_for=True)
movie_objs = info_selector.populate_movie_objs()
write_info = info_selector.write_to_txt()
Reply
#4
Quote:how would I write the statements without the reference to the object?

Sorry, I'm not following. Which statements do you want to write without referring to which object?

In your #2, director_known_for{"director1"} is just a list. So you can build it up by appending to it. I think your question is related to that, but I'm not sure.
Reply
#5
I may not be understanding your question...
Quote:Why are the elements like k['title'] used repeatedly? Since k isn't changing, this will be the same in all the items.
The results that are being accessed are for movies that the searched person has directed. Therefore in each iteration, the data in k should be different because it references a different movie.
Is there a better way to do this? *points to username*

After some sleep and re-writing this response a few times... I'm going to give the dicts/lists another try and report back later. Hopefully your confusion over my question has gotten me to the answer hahaha
Reply
#6
In the original post, that seemed odd because nothing was modifying k. But if you are changing k during the assembly, then that would be okay.
Reply
#7
This turned out to not be as difficult as my brain was making it. I didn't realize dicts could be created while iterating like this so... Awesome!

Here's the updated director_known_for block.

        if bool(self.director_known_for):
            for i in directors:
                director_known_for1[str(i)] = []
                director_search = search.person(query=i)
                for j in director_search['results']:
                    for k in  j['known_for']:
                        director_known_for1[i].append(f"{k['title']} {k['release_date']} {tmdb_url} {k['id']}")
Thanks for your help bowlofred!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Sort a list of dictionaries by the only dictionary key Calab 1 453 Oct-27-2023, 03:03 PM
Last Post: buran
  Access list of dictionaries britesc 4 1,028 Jul-26-2023, 05:00 AM
Last Post: Pedroski55
  Class-Aggregation and creating a list/dictionary IoannisDem 1 1,884 Oct-03-2021, 05:16 PM
Last Post: Yoriz
  Delete list while iterating shantanu97 1 1,866 Jun-06-2021, 11:59 AM
Last Post: Yoriz
  function that returns a list of dictionaries nostradamus64 2 1,701 May-06-2021, 09:58 PM
Last Post: nostradamus64
  convert List with dictionaries to a single dictionary iamaghost 3 2,805 Jan-22-2021, 03:56 PM
Last Post: iamaghost
  Creating list of lists from generator object t4keheart 1 2,162 Nov-13-2020, 04:59 AM
Last Post: perfringo
  Creating a dictionary from a list Inkanus 5 3,110 Nov-06-2020, 06:11 PM
Last Post: DeaD_EyE
  Help accessing elements of list of dictionaries Milfredo 6 2,783 Sep-07-2020, 01:32 AM
Last Post: Milfredo
  Accessing values in list of dictionaries pythonnewbie138 2 2,084 Aug-02-2020, 05:02 PM
Last Post: pythonnewbie138

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020