grab a value from a dict and insert in a new dict in Python

Viewed 75

I have two dictionaries:

people = [
    {
    'name' : 'Ben',
    'par_one' : ['a','b','c'],
    'par_two' : [1,2,3,4,5]},
    {
    'name' : 'Jhon',
    'par_one' : ['x','c','g','z'],
    'par_two' : [3,6,9,]
}]

d2 = {
    'name' : 'Ben',
    'par_one' : 'random',
    'par_two' : 5
}

I need to modify the value of d2 only if the value of par_one is "random", in this case, I want to overwrite "random" with the list in people that has the same key. The problem is that the list of people needs to have more dictionaries: so I have to find the correct dict (in the example case, the one with 'name' = 'Ben'), and then find the proper key and copy the value.

My expected output is:

final = {
    'name' : 'Ben',
    'par_one' : ['a','b','c'],
    'par_two' : 5
}

thanks a lot!!

5 Answers

In the names are unique, you can build a second dictionary from people, to simplify the code.

dict_people = {x["name"]:x for x in people}

You can do the check:

final = d2
if d2["par_one"] == "random":
    name = d2["name"]
    final["par_one"]= dict_people[name]["par_one"]

print(final)

It seems you only need to change the 'par_one' attribute.

if d2['par_one'] == 'random':
    selected_person = [person for person in people if person['name'] == d2['name']][0]
    d2['par_one'] = selected_person['par_one']

This will solve the problem!

What we are doing is getting the list of all people having the name d2['name'] (e.g. 'Ben'). Then we are selecting the 1st index of this list (Assuming that there will be one and only one person with this name).

Try this:

final = d2.copy()

if final["par_one"] == "random":
    for item in people:
        if item["name"] == final["name"]:
            final["par_one"] = item["par_one"]
            break  # no need to continue

print(final)

Output:

{'name': 'Ben', 'par_one': ['a', 'b', 'c'], 'par_two': 5}

I'm assuming d2 is rather a list of dictionaries rather than one dictionary. I'll call this list input.

def replace_key(people, input):
    for dct in input:
       if dct['par_one'] == 'random':
           for person in people:
              if person['name'] == dct['name']:
                   dct['par_one'] = person['par_one']
                   break

When the function exists, the argument you passed for input will contain the keys. However, there is a thing that may really end up confusing you. par_key is a list. When you assign person['par_one'] to dct[par_one], YOU ARE NOT COPYING THE LIST. If you modified the list in one dictionary, it will also reflect in the other dictionary. This is because lists are references. If you truly want a copy which you have mentioned in your question, then instead of:

 dct['par_one'] = person['par_one']

do this:

 dct['par_one'] = person['par_one'][:]

or:

 dct['par_one'] = list(person['par_one'])

Also, this code modifies the dictionary by actually changing the values. If you want the results in a fresh dictionary without modifying input, do this:

def replace_key(people, input):
   final = input.copy()
    for dct in final:
       if dct['par_one'] == 'random':
           for person in people:
              if person['name'] == dct['name']:
                   dct['par_one'] = person['par_one'][:]
                   break
    return final

Here is one more suggestion for you, without caring about which key is 'random'.

final = {}
for d2k in d2.keys():
     if d2[d2k] is 'random':
         for person in people:
             if person['name'] is d2['name']: 
                 final[d2k] = person[d2k]
                 break
     else:
         final[d2k] = d2[d2k]
Related