js352
js352

Reputation: 374

Three lists in a dictionary

I have three lists which I want to convert into a list of dictionaries following this structure:

Expected output:

[{'Chamber pop': {'url': '/wiki/Chamber_pop', 'description': 'xxx'},
{'Dance-punk': {'url': '/wiki/Dance-punk', 'description': 'yyy'}, 
{'Dream pop': {'url': '/wiki/Dream_pop', 'description': 'zzz'},
{'Dunedin Sound': {'url': 'Dunedin_Sound', 'description': 'aaa'}]

Lists:

names = ['Chamber pop',
 'Dance-punk',
 'Dream pop',
 'Dunedin Sound',]

urls = ['/wiki/Chamber_pop',
 '/wiki/Dance-punk',
 '/wiki/Dream_pop',
 '/wiki/Dunedin_Sound']

description = ["xxx","yyy","zzz","aaa"]

What I've tried so far is:

res = {} 
for x in names: 
  for y in url:
      res[x] = {}
      res[x]["url"] = y

However the output of this code is:

{'Chamber pop': {'url': '/wiki/Twee_pop'},
 'Dance-punk': {'url': '/wiki/Twee_pop'},
 'Dream pop': {'url': '/wiki/Twee_pop'},
 'Dunedin Sound': {'url': '/wiki/Twee_pop'}}

As you may see, the url value keeps repeating. I guess it's because somewhere is overwriting the value. Also, it does not have the expected structure as it all falls inside a dictionary.

What am I doing wrong? Would appreciate any help.

Thank you

Upvotes: 0

Views: 40

Answers (2)

Meny Issakov
Meny Issakov

Reputation: 1421

It looks as you want to iterate over the lists together and match them by the index (first name to the first url, and vice versa).

What you're doing, is for every name in your names list, you're iterating over all of the URLs, and assigning in each iteration, you're actually overwriting the url value. this ends up with the last url in your urls list to always be the assigned value for each name.

If you'll add prints, you'll see that the last url for each name, is the last one on the list:

res = {} 
for x in names: 
    print(x)
    for y in urls:
        print(x, y)
        res[x] = {}
        res[x]["url"] = y

yields:

Chamber pop
Chamber pop /wiki/Chamber_pop
Chamber pop /wiki/Dance-punk
Chamber pop /wiki/Dream_pop
Chamber pop /wiki/Dunedin_Sound
Dance-punk
Dance-punk /wiki/Chamber_pop
Dance-punk /wiki/Dance-punk
Dance-punk /wiki/Dream_pop
Dance-punk /wiki/Dunedin_Sound
Dream pop
Dream pop /wiki/Chamber_pop
Dream pop /wiki/Dance-punk
Dream pop /wiki/Dream_pop
Dream pop /wiki/Dunedin_Sound
Dunedin Sound
Dunedin Sound /wiki/Chamber_pop
Dunedin Sound /wiki/Dance-punk
Dunedin Sound /wiki/Dream_pop
Dunedin Sound /wiki/Dunedin_Sound

What you can do is match them by the index. of course, there's a hidden assumption here, that all of your lists are with the same length.

final_res_dict = {}
for index in range(len(names)):
    name = names[index]
    final_res_dict[name] = {"url": urls[index], "description": description[index]}
    

which yields:

{'Chamber pop': {'url': '/wiki/Chamber_pop', 'description': 'xxx'},
 'Dance-punk': {'url': '/wiki/Dance-punk', 'description': 'yyy'},
 'Dream pop': {'url': '/wiki/Dream_pop', 'description': 'zzz'},
 'Dunedin Sound': {'url': '/wiki/Dunedin_Sound', 'description': 'aaa'}}

Upvotes: 1

Mark
Mark

Reputation: 92460

Typically you would zip() your lists allowing you to iterate over them in parallel. Then you could simply use a dict comprehension:

names = ['Chamber pop','Dance-punk','Dream pop', 'Dunedin Sound',]  
urls = ['/wiki/Chamber_pop', '/wiki/Dance-punk', '/wiki/Dream_pop','/wiki/Dunedin_Sound']  
description = ["xxx","yyy","zzz","aaa"]

res = {n: {'url':u, 'description':d} 
 for n, u, d in zip(names, urls, description)}

which makes res =

{'Chamber pop': {'url': '/wiki/Chamber_pop', 'description': 'xxx'},
 'Dance-punk': {'url': '/wiki/Dance-punk', 'description': 'yyy'},
 'Dream pop': {'url': '/wiki/Dream_pop', 'description': 'zzz'},
 'Dunedin Sound': {'url': '/wiki/Dunedin_Sound', 'description': 'aaa'}}

Upvotes: 1

Related Questions