简体   繁体   中英

Add same key but different values (coming from list) to a nested dictionary

I managed to scrape some content and organize it as a nested dictionary like this.

country_data = {
    "US": {
        "People": [
            {
                "Title": "Pres.",
                "Name": "Joe"
            },
            {
                "Title": "Vice",
                "Name": "Harris"
            }
        ]
    }
}

Then I have this list

tw_usernames = ['@user1', '@user2']

that I'd like to use to add each item list to each entry of the People nested dictionary. I have done some research about list and dict comprehension but I cannot find something to make it work, so I tried with this basic code but of course it's not exactly what I want, as it returns all the items list.

for firstdict in country_data.values():
    for dictpeople in firstdict.values():
        for name in dictpeople:
            name['Twitter'] = tw_usernames
            print(name)

So how would you do it to get dictionary like this?

country_data = {
    "US": {
        "People": [
            {
                "Title": "Pres.",
                "Name": "Joe",
                "Twitter": "@user1"
            },
            {
                "Title": "Vice",
                "Name": "Harris",
                "Twitter": "@user2"
            }
        ]
    }
}

Thanks in advance for any tip that could teach me.

You can zip the list of sub-dicts with the list of usernames and iterate over the resulting sequence of pairs to add a Twitter key to each sub-dict:

for person, username in zip(country_data['US']['People'], tw_usernames):
    person['Twitter'] = username

With your sample input, country_data would become:

{'US': {'People': [{'Title': 'Pres.', 'Name': 'Joe', 'Twitter': '@user1'}, {'Title': 'Vice', 'Name': 'Harris', 'Twitter': '@user2'}]}}

Source code

def add_twitter_usernames_to_users(country_data: dict, tw_usernames: [str]):
    for tw_username in tw_usernames:
        country_data["US"]["People"][tw_usernames.index(tw_username)]["Twitter"] = tw_username

    return country_data

Test

def test_add_twitter_usernames_to_users():
    country_data = {
        "US": {
            "People": [
                {
                    "Title": "Pres.",
                    "Name": "Joe"
                },
                {
                    "Title": "Vice",
                    "Name": "Harris"
                }
            ]
        }
    }

    tw_usernames = ['@user1', '@user2']

    updated_country_data: dict = so.add_twitter_usernames_to_users(country_data, tw_usernames)

    assert updated_country_data["US"]["People"][0]["Twitter"] == "@user1"
    assert updated_country_data["US"]["People"][1]["Twitter"] == "@user2"

Try this. I have just added index in your logic. It will pick the username according to the index

idx = 0
tw_usernames = ['@user1', '@user2']
for firstdict in country_data.values():
    for dictpeople in firstdict.values():
        for name in dictpeople:
            name['Twitter'] = tw_usernames[idx]
            idx+=1

print(country_data)

output

{
   "US":{
      "People":[
         {
            "Title":"Pres.",
            "Name":"Joe",
            "Twitter":"@user1"
         },
         {
            "Title":"Vice",
            "Name":"Harris",
            "Twitter":"@user2"
         }
      ]
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM