Iterate through two keys in Python

Viewed 123

I'm looking forward to iterating through both my keys here(models and dealers) and recording that in a csv. Maybe because i'm new to py or the way i'm used to like in sql, i'm not quite getting the idea of looping through two keys and getting the data. currently i'm doing a basic loop to extract the data, Any insight on how to address this would be really helpful

My code:

for x in data['models']:
   for y in data['models'][x]:
       fetch={'brand': x, 'model':y}
       resul.append(fetch)

for a in data['dealers']:
   for b in data['dealers'][a]:
       fetch={'brand': a, 'dealer':b}

My input:

data={ 
 "models" : 
       {
          "ford" : [ "ranger","mustang","ecosport","ikon"],
        "nissan" : ["gt","terrano"],
        "tesla" : ["cyber truck","model x","model s","model s2"],
        "honda" : ["civic", "accord"]
        },
    
 "dealers":
        {
         "tesla": [ "california", "newyork", "ohio"],
         "ford" : ["new jersey","hongkong","beijing","delhi","telaviv","ottawa"],
         "gm" : ["new york","washington dc"],
         "nissan" : ["dubai","saudi arabia"]
         }
}

Output:

| brand | models | dealers|
|-------|--------|---------|
|ford   | ranger | new jery|
|ford   | mustang| hongkong |
|ford   | ecosport| beijing |
|ford   | ikon    | delhi|
|ford   |         | telaviv |
|ford   |         | ottawa |
|nissan | gt      | dubai |
|nissan | terrano | saudi arabia|
|tesla  |cyber truck| california|
|tesla  | model x   | newyork   |
|tesla  | model s   | ohio      |
|tesla  | model s2  |           |
|honda  | civic     |           |
|honda  | accord    |           |
|gm     | new york  |           |
|gm     | washington dc|        |
4 Answers

As you have tagged the question with pandas here is one possible approach that significantly involve lots of pandas operations including stack, explode and reshaping using unstack

df = pd.DataFrame(data).stack().explode().to_frame()
df = df.set_index(df.groupby(level=[0, 1]).cumcount(), append=True)[0]\
       .unstack(level=1).droplevel(1).rename_axis('brand').reset_index()

print(df)

     brand        dealers       models
0     ford     new jersey       ranger
1     ford       hongkong      mustang
2     ford        beijing     ecosport
3     ford          delhi         ikon
4     ford        telaviv          NaN
5     ford         ottawa          NaN
6       gm       new york          NaN
7       gm  washington dc          NaN
8    honda            NaN        civic
9    honda            NaN       accord
10  nissan          dubai           gt
11  nissan   saudi arabia      terrano
12   tesla     california  cyber truck
13   tesla        newyork      model x
14   tesla           ohio      model s
15   tesla            NaN     model s2

A simple refactoring will suffice.

for key in ['models', 'dealers']:
    for x in data[key]:
        for y in data[key][x]:
            fetch = {'brand': x, key: y}
            result.append(fetch)

This works because the structure of both values is the same, only the name of the key mapped to them differs.

for key,value in data.items():
    if key=='models':
        for brand,model_list in value.items():
            for model in model_list:
                fetch={'brand': brand, 'model':model}
                resul.append(fetch)
                continue
    elif key=='dealers':
        for brand,dealer_list in value.items():
            for dealer in model_list:
                fetch={'brand': brand, 'dealer':dealer}
                resul.append(fetch)
                continue
    else:
        print("no brand available")

       
    

There may exist a prettier solution, but this works.

data={ 
 "models" : 
       {
          "ford" : [ "ranger","mustang","ecosport","ikon"],
        "nissan" : ["gt","terrano"],
        "tesla" : ["cyber truck","model x","model s","model s2"],
        "honda" : ["civic", "accord"]
        },
    
 "dealers":
        {
         "tesla": [ "california", "newyork", "ohio"],
         "ford" : ["new jersey","hongkong","beijing","delhi","telaviv","ottawa"],
         "gm" : ["new york","washington dc"],
         "nissan" : ["dubai","saudi arabia"]
         }
}

keys = list(data["models"].keys()) + list(data["dealers"].keys())
keys = set(keys)
def pad_lists(key,a,b):
    if a is None:
        a = []
    if b is None:
        b = []
    if len(a)>len(b):
        b += [None for i in range(len(a)-len(b))]
    elif len(a)<len(b):
        a += [None for i in range(len(b)-len(a))]
    key_list = [key]*len(a)    
    return key_list,a,b
    
df_brands = []
df_models = []
df_dealers = []
for key in keys:
    brands,a,b = pad_lists(key,
                           data['models'].get(key),
                           data['dealers'].get(key)
                          )
    df_brands.extend(brands)
    df_models.extend(a)
    df_dealers.extend(b)
df = pd.DataFrame.from_dict({"brands":df_brands,"models":df_models,"dealers":df_dealers})\
        .fillna('')

<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>brands</th>
      <th>models</th>
      <th>dealers</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>ford</td>
      <td>ranger</td>
      <td>new jersey</td>
    </tr>
    <tr>
      <th>1</th>
      <td>ford</td>
      <td>mustang</td>
      <td>hongkong</td>
    </tr>
    <tr>
      <th>2</th>
      <td>ford</td>
      <td>ecosport</td>
      <td>beijing</td>
    </tr>
    <tr>
      <th>3</th>
      <td>ford</td>
      <td>ikon</td>
      <td>delhi</td>
    </tr>
    <tr>
      <th>4</th>
      <td>ford</td>
      <td></td>
      <td>telaviv</td>
    </tr>
    <tr>
      <th>5</th>
      <td>ford</td>
      <td></td>
      <td>ottawa</td>
    </tr>
    <tr>
      <th>6</th>
      <td>tesla</td>
      <td>cyber truck</td>
      <td>california</td>
    </tr>
    <tr>
      <th>7</th>
      <td>tesla</td>
      <td>model x</td>
      <td>newyork</td>
    </tr>
    <tr>
      <th>8</th>
      <td>tesla</td>
      <td>model s</td>
      <td>ohio</td>
    </tr>
    <tr>
      <th>9</th>
      <td>tesla</td>
      <td>model s2</td>
      <td></td>
    </tr>
    <tr>
      <th>10</th>
      <td>honda</td>
      <td>civic</td>
      <td></td>
    </tr>
    <tr>
      <th>11</th>
      <td>honda</td>
      <td>accord</td>
      <td></td>
    </tr>
    <tr>
      <th>12</th>
      <td>gm</td>
      <td></td>
      <td>new york</td>
    </tr>
    <tr>
      <th>13</th>
      <td>gm</td>
      <td></td>
      <td>washington dc</td>
    </tr>
    <tr>
      <th>14</th>
      <td>nissan</td>
      <td>gt</td>
      <td>dubai</td>
    </tr>
    <tr>
      <th>15</th>
      <td>nissan</td>
      <td>terrano</td>
      <td>saudi arabia</td>
    </tr>
  </tbody>
</table>

Related