How do I create new lists dynamically and add these multiple lists inside a parent list as a value in a dictionary?

Question:

I need to create a Panda Data frame for Pokémon’s using a dictionary which needs to contain the attribute name (Ex: such as "height" of Chameleon and Charmander) as the key and the respective value (Ex: Height value of Chameleon and Charmander as 11 and 6) as the value.

To start with, my code needs to have multiple lists for each attribute I need: Name, height, and Type. These lists should be added as keys and values to the dictionary in order to create a data frame.

import requests
import json
import pandas as pd

pokemons = ["charmeleon","charmander"]
name, height, weight, types_l = [],[],[],[]


for pokemon in pokemons:
  res = requests.get(f"https://pokeapi.co/api/v2/pokemon/{pokemon.lower()}")
  data = json.loads(res.text)
  name.append(pokemon)
  height.append(data["height"])
  types = (data["types"])
  
  for type in types:
    types_l.append(type['type']['name'])


poke_dictionary = {
  "Name" : name,
  "Height" : height,
  "Weight" : weight,
  "Type" : types_l
}
print(poke_dictionary)
df_pokedata = pd.DataFrame(poke_dictionary)
print(df_pokedata)

With the Pokémon’s – Chameleon and Charmander, the output of the dictionary is as below. Notice that the length of the values in the dictionary is the same

{'Name': ['charmeleon', 'charmander'], 'Height': [11, 6], 'Type': ['fire', 'fire']}

However, some Pokémons have multiple types (For example: Bulbasaur which is Grass and Poison). Hence the dictionary with bulbasaur and charmander becomes the below. Notice different length of values as seen in type

{'Name': ['bulbasaur', 'charmander'], 'Height': [7, 6], 'Type': ['grass', 'poison', 'fire']}

In order for me to get this into the data frame, the length of values needs to be identical, and hence I will need to create multiple lists inside a list such that each list inside this list is taken as a value as shown below:

{'Name': ['bulbasaur', 'charmander'], 'Height': [7, 6], 'Type': [['grass', 'poison'], ['fire']]}
Asked By: Rakesh

||

Answers:

One way to make each entry in the type array a list by using a list comprehension as follows:

import requests
import json
import pandas as pd

pokemons = ["bulbasaur" ,"charmeleon","charmander"]
name, height, weight, types_l = [],[],[],[]


for pokemon in pokemons:
  res = requests.get(f"https://pokeapi.co/api/v2/pokemon/{pokemon.lower()}")
  data = json.loads(res.text)
  name.append(pokemon)
  height.append(data["height"])
  types = (data["types"])
  
  # EDIT:  Changed this line to remove the square brackets (see comments)
  types_l.append( ",".join([ type['type']['name'] for type in types ]) )


poke_dictionary = {
  "Name" : name,
  "Height" : height,
  "Type" :  types_l  
}
print(poke_dictionary)
df_pokedata = pd.DataFrame(poke_dictionary)
print(df_pokedata)

Results:

$ python poke 
{'Name': ['bulbasaur', 'charmeleon', 'charmander'], 'Height': [7, 11, 6], 'Type': [['grass', 'poison'], ['fire'], ['fire']]}
         Name  Height             Type
0   bulbasaur       7  [grass, poison]
1  charmeleon      11           [fire]
2  charmander       6           [fire]

You might appreciate knowing that the request object has a json() method that you can invoke like this:

data = res.json()  # roughly the same as: data = json.loads(res.text)

Also, since you weren’t setting the weights, I removed it from the solution.

Answered By: Mark

just create another empty list to store all the types information and append the list to the large list at the end of the outer for loop:

import requests
import json
import pandas as pd

pokemons = ["charmeleon","charmander","bulbasaur"]
name, height, weight, types_l = [],[],[],[]


for pokemon in pokemons:
  res = requests.get(f"https://pokeapi.co/api/v2/pokemon/{pokemon.lower()}")
  data = json.loads(res.text)
  name.append(pokemon)

  # initiate new empty lists
  this_type_list = []

  height.append(data["height"])
  types = (data["types"])

  for type in types:
      this_type_list.append(type['type']['name'])
  types_l.append(this_type_list)
  
poke_dictionary = {
  "Name" : name,
  "Height" : height,
  "Type" : types_l
}

df_pokedata = pd.DataFrame(poke_dictionary)
print(df_pokedata)



    Name          Height             Type
0  charmeleon      11               [fire]
1  charmander       6               [fire]
2   bulbasaur       7               [grass, poison]
Answered By: Mengxiao Li
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.