37

I've been stuck on this question for quite sometime and just can't figure it out. I just want to be able to understand what I'm missing and why it's needed. What I need to do is make a function which adds each given key/value pair to the dictionary. The argument key_value_pairs will be a list of tuples in the form (key, value).

def add_to_dict(d, key_value_pairs):

    newinputs = [] #creates new list
    for key, value in key_value_pairs:
        d[key] = value #updates element of key with value
        if key in key_value_pairs:
            newinputs.append((d[key], value)) #adds d[key and value to list
    return newinputs

I can't figure out how to update the "value" variable when d and key_value_pairs have different keys.

The first three of these scenarios work but the rest fail

>>> d = {}
>>> add_to_dict(d, [])
[]
>>> d
{}

>>> d = {}
>>> add_to_dict(d, [('a', 2])
[]
>>> d
{'a': 2}

>>> d = {'b': 4}
>>> add_to_dict(d, [('a', 2)])
[]
>>> d
{'a':2, 'b':4}

>>> d = {'a': 0}
>>> add_to_dict(d, [('a', 2)])
[('a', 0)]
>>> d
{'a':2}

>>> d = {'a', 0, 'b': 1}
>>> add_to_dict(d, [('a', 2), ('b': 4)])
[('a', 2), ('b': 1)]
>>> d
{'a': 2, 'b': 4}

>>> d = {'a': 0}
>>> add_to_dict(d, [('a', 1), ('a': 2)])
[('a', 0), ('a':1)]
>>> d
{'a': 2}
8
  • 1
    What's wrong with dict.update? Commented Apr 17, 2015 at 9:06
  • 1
    Sorry, are those outputs what you're getting, or what you want? Commented Apr 17, 2015 at 9:06
  • 2
    Can you show the output you get vs the output you expect in each case? Commented Apr 17, 2015 at 9:08
  • 2
    key in key_value_pairs will usually be false, because key_value_pairs is a list of tuples, but in most cases key is not a tuple Commented Apr 17, 2015 at 9:10
  • 2
    Your question is not clear for me (and for other people too I guess as every answer is different) Do you consider your first example with add_to_dict(d, [('a', 2)]) as invalid ? Would you expect {'a':2, 'a': 0} ? Commented Apr 17, 2015 at 9:33

8 Answers 8

53

Python has this feature built-in:

>>> d = {'b': 4}
>>> d.update({'a': 2})
>>> d
{'a': 2, 'b': 4}

Or given you're not allowed to use dict.update:

>>> d = dict(d.items() + {'a': 2}.items())   # doesn't work in python 3
Sign up to request clarification or add additional context in comments.

5 Comments

I have to achieve this by only using loops and statements
@KanadeSwag: This is "only a statement". Those rules are meaningless, as they allow all python code
I meant if statements, sorry
@KanadeSwag: That's also a false set of rules, as you also need assignment, key access, arithmetic. Which builtin functions are you allowed to use, and which are you not?
Notes about dict.update(): (1) It changes the existing dict, (2) It returns None, and (3) It overwrites existing items (as does the dictionary merge operator dict1 | dict2).
31

With python 3.9 you can use an |= update operator:

>>> d = {'b': 4}
>>> d |= {'a': 2}
>>> d
{'a': 2, 'b': 4}

Comments

12

Here's a more elegant solution, compared to Eric's 2nd snippet

>>> a = {'a' : 1, 'b' : 2}
>>> b = {'a' : 2, 'c' : 3}
>>> c = dict(a, **b)
>>> a
{'a': 1, 'b': 2}
>>> b
{'a': 2, 'c': 3}
>>> c
{'a': 2, 'b': 2, 'c': 3}

It works both in Python 2 and 3

And of course, the update method

>>> a
{'a': 1, 'b': 2}
>>> b
{'a': 2, 'c': 3}
>>> a.update(b)
>>> a
{'a': 2, 'b': 2, 'c': 3}

However, be careful with the latter, as might cause you issues in case of misuse like here

>>> a = {'a' : 1, 'b' : 2}
>>> b = {'a' : 2, 'c' : 3}
>>> c = a
>>> c.update(b)
>>> a
{'a': 2, 'b': 2, 'c': 3}
>>> b
{'a': 2, 'c': 3}
>>> c
{'a': 2, 'b': 2, 'c': 3}

3 Comments

What's the misuse in the last example?
@xuiqzy c is just a shallow copy which still refers to a. When using .update(b), both c and a were updated since they referred to the same objects. You can check this with id(a) == id(c). To create a new object, one way is to create c like this: c = dict(a). Then, id(a) == id(c) will fail and c.update(b) will produce: {'a': 2, 'b': 2, 'c': 3}, leaving a unchanged at {'a': 1, 'b': 2}.
@MarkMoretto Ok thanks, that's how I read it. I just wasn't sure that this effect was not intended.
10

The new version of Python3.9 introduces two new operators for dictionaries: union (|) and in-place union (|=). You can use | to merge two dictionaries, while |= will update a dictionary in place. Let's consider 2 dictionaries d1 and d2

d1 = {"name": "Arun", "height": 170}
d2 = {"age": 21, "height": 170}
d3 = d1 | d2 # d3 is the union of d1 and d2
print(d3)

Output:

{'name': 'Arun', 'height': 170, 'age': 21}

Update d1 with d2

d1 |= d2
print(d1)

Output:

{'name': 'Arun', 'height': 170, 'age': 21}

You can update d1 with a new key weight as

d1 |= {"weight": 80}
print(d1)

Output:

{'name': 'Arun', 'height': 170, 'age': 21, 'weight': 80}

Comments

2

I think this post explains it well: Dictionary Merge and Update Operators in Python 3.9:

Here a summary:

The Dictionary Update Operator

Dictionary x is being updated by the dictionary y

x.update(y)
print(x)

The Dictionary Merge Operator:

Fuse them into a new one. Having:

x = {"key1": "value1 from x", "key2": "value2 from x"}
y = {"key2": "value2 from y", "key3": "value3 from y"}

Old way:

z = {**x, **y}
print(z)

New way:

z = x | y
print(z)

Comments

0

So if I understand you correctly you want to return a list of of tuples with (key, old_value) for the keys that were replaced.

You have to save the old value before you replace it:

def add_to_dict(d, key_value_pairs):

    newinputs = [] #creates new list
    for key, value in key_value_pairs:
        if key in d:
            newinputs.append((key, d[key]))
        d[key] = value #updates element of key with value
    return newinputs

Comments

0

Each key in a python dict corresponds to exactly one value. The cases where d and key_value_pairs have different keys are not the same elements.

Is newinputs supposed to contain the key/value pairs that were previously not present in d? If so:

def add_to_dict(d, key_value_pairs):
  newinputs = []
  for key, value in key_value_pairs:
    if key not in d:
      newinputs.append((key, value))
    d[key] = value
  return newinputs

Is newinputs supposed to contain the key/value pairs where the key was present in d and then changed? If so:

def add_to_dict(d, key_value_pairs):
  newinputs = []
  for key, value in key_value_pairs:
    if key in d:
      newinputs.append((key, value))
    d[key] = value
  return newinputs

Comments

0

If I understand you correctly, you only want to add the keys that do not exist in the dictionary. Here is the code:

def add_to_dict(d, key_value_pairs):
    newinputs = [];
    for key, value in key_value_pairs:
        if key not in d.keys():
            d[key] = value
            newinputs.append((key, value));
    return newinputs

For each key in new key,value pairs list you have to check if the key is new to the dictionary and add it only then. Hope it helps ;)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.