3

I'm trying to call a function using a name of a var dynamically, but I don't know if this is possible, something like that:

fight_movies = list() # var how I want to use in function call
win_movies = list() # var how I want to use in function call
knowledge_movies = list() # var how I want to use in function call
biography_movies = list() # var how I want to use in function call

for genre in genres:
    .... Ommited #\/\/\/\/\/\/ Here is where I call the function
    write_jsonl(genre + '_movies', genre, rating, title, genre) #here is the call of the function


def write_jsonl(movie_list, genre, rating, title, json_name):
    dict = {'title': title, 'genre': genre, 'rating': rating}
    movie_list.append(dict)
    # print(action_movies)
    with jsonlines.open(json_name+'.jsonl', mode='w') as writer:
        writer.write(movie_list)

I'm trying to pass the variable name as a list dynamically, but I'm not sure if that's possible in python, any suggestions?

Error: Traceback (most recent call last):
  File "bucky.py", line 58, in <module>
    web_crawling()
  File "bucky.py", line 34, in web_crawling
    write_jsonl(genre + '_movies', genre, rating, title, genre)
  File "bucky.py", line 52, in write_jsonl
    movie_list.append(dict)
AttributeError: 'str' object has no attribute 'append'
Cœur
  • 37,241
  • 25
  • 195
  • 267

3 Answers3

1

You could find your variables in locals()/globals() like so

for genre in genres:
    #.... Ommited \/\/\/\/\/\/ Here is where I call the function
    write_jsonl(locals()[genre + '_movies'], genre, rating, title, genre) #here is the call of the function
Filip Młynarski
  • 3,534
  • 1
  • 10
  • 22
1

As suggested by most use a dictionary, and then if you want and I think what you are intending for it to do is to then store the dictionary in a list. However, your code shows a problem where you passed a string for what I believe you intend to be a list.

def write_jsonl(movie_list, genre, rating, title, json_name):
    d= {'title': title, 'genre': genre, 'rating': rating}
    movie_list.append(d) #<-- movie_list based on your traceback is a str
    # print(action_movies)
    with jsonlines.open(json_name+'.jsonl', mode='w') as writer:
        writer.write(movie_list)

The example below works as intended:

all_movie_list = []

def write_jsonl(movie_list, genre, rating, title, json_name):
    d= {'title': title, 'genre': genre, 'rating': rating}
    movie_list.append(d)
    # print(action_movies)
    with jsonlines.open(json_name+'.jsonl', mode='w') as writer:
        writer.write(movie_list)

write_jsonl(all_movie_list,'Crime','10','Godfather','test')

all_movie_list
[{'title': 'Godfather', 'genre': 'Crime', 'rating': '10'}]

The better way is to store your list of titles by genre in a dictionary, you can use the defaultdict data model from the Python standard library for that.

from collections import defaultdict
movie_list = defaultdict(list)

def write_jsonl(movie_list, genre, rating, title, json_name):
    d= {'title': title, 'genre': genre, 'rating': rating}
    movie_list['{}_movies'.format(genre)].append(d)
    # print(action_movies)
    with jsonlines.open(json_name+'.jsonl', mode='w') as writer:
        writer.write(movie_list)

movie_list
>>defaultdict(list,
            {'Crime_movies': [{'title': 'Godfather',
               'genre': 'Crime',
               'rating': '10'}]})

movie_list['Crime_movies']
>>[{'title': 'Godfather', 'genre': 'Crime', 'rating': '10'}]

Also do not use inbuilt method or reserved names as variables, I replaced your dict variable to just d.

BernardL
  • 5,162
  • 7
  • 28
  • 47
1

Just use a dictionary:

genres_dict = {k: [] for k in ('fight', 'win', 'knowledge', 'biography')}

for genre in genres:
    write_jsonl(genres_dict[genre], genre, rating, title, genre)

A variable number of variable is not the recommended approach.

Related: How do I create a variable number of variables?.

jpp
  • 159,742
  • 34
  • 281
  • 339