0

I have a dictionary of dog owners and i need to write a function update_age() that will update the dogs owner's ages in the dictionary. Here is an example:

dog_owners = {("John", "Malkovic", 22): ["Fido"],
              ("Jake", "Smirnoff", 18): ["Butch"],
              ("Simon", "Ng", 32): ["Zooma", "Rocky"],
              ("Martha", "Black", 73): ["Chase"]}

So the key is a tuple in which the numbers 22, 18, 32, and 73 represent age. The function update_age() has 3 arguments: name of dictionary, tuple with 3 elements, the number that should change the number from the tuple.

Example:

update_age(dog_owners, ("Jake", "Smirnoff", 18), 22)
dog_owners[("Jake", "Smirnoff", 22)] == ['Butch']
dog_owners.get(("Jake", "Smirnoff", 18)) is None

I tried to do:

def update_age(owners, owner, new_age):
    b = (new_age,)
    return owner[0:2] + b

but it is not correct because the original key still has the previous value and if i write:

print(update_age(dog_owners, ("Jake", "Smirnoff", 18), 22))   # for check
print(dog_owners.get(("Jake", "Smirnoff", 18)) is None)

the answer will be

('Jake', 'Smirnoff', 22)
False

So it means that my original key still has its previous value. How can I change it? May be I should try pop() and than add a new tuple to the key, but I don't know how.

martineau
  • 119,623
  • 25
  • 170
  • 301
Ruslan
  • 43
  • 6
  • Does this answer your question? [Change the name of a key in dictionary](https://stackoverflow.com/questions/4406501/change-the-name-of-a-key-in-dictionary) – kiran_raj_r Oct 18 '20 at 20:34
  • You cann't change the keys of dictionary, you can only remove the existing key, value pair and replace them with a new one — there are several ways to do that. It has nothing to do with that fact that tuples are immutable, so the answer you have currently accepted is incorrect in that respect. – martineau Oct 18 '20 at 20:53

2 Answers2

1

Dict keys are exactly that: keys. You cannot "update" a key; it's the defining value. You have to delete the original and replace it with the new one; the two objects are not at related.

However, the problem here seems to be one of design: you stored information you want to alter as part of the key, for reasons you have not explained. Instead, make that information part of the entry's value:

          ("Simon Ng"): 
              {age: 32,
               dogs: ["Zooma", "Rocky"]},

Perhaps an even better idea would be to trade in your dict for a data frame.

Prune
  • 76,765
  • 14
  • 60
  • 81
1

You can replace the keys to achieve this and moreover tuples are immutable.

You can also refactor code and restructure dictionary to make this use case achieve in simpler way but just in case if you want the way it is then you can check out below working snippet.

def update_age(owners, owner, new_age):
    if owner in owners:   # check if owner tuple exist in dictionary keys
        owner_list = list(owner)   # convert to list since tuples are immutable
        owner_list.pop(-1)   # remove last value
        owner_list.append(new_age)  # add new age at last

        owners.update({tuple(owner_list): owners.get(owner)})  # add new key updated tuple
        owners.pop(owner)  # remove old key
    return owners


dog_owners = {("John", "Malkovic", 22): ["Fido"],
              ("Jake", "Smirnoff", 18): ["Butch"],
              ("Simon", "Ng", 32): ["Zooma", "Rocky"],
              ("Martha", "Black", 73): ["Chase"]
              }

print(update_age(dog_owners, ("Jake", "Smirnoff", 18), 22))

Output:

{('John', 'Malkovic', 22): ['Fido'], ('Simon', 'Ng', 32): ['Zooma', 'Rocky'], ('Martha', 'Black', 73): ['Chase'], ('Jake', 'Smirnoff', 22): ['Butch']}

Tuples are immutable checkout why

Shakeel
  • 1,869
  • 15
  • 23
  • The immutability of tuples has nothing to do with it (strings are mutable, too). In fact all dictionary keys are immutable. – martineau Oct 18 '20 at 20:54
  • My primary point is that the issue has nothing to do with the immutability of the keys, it's because you cannot change the key of a value in a dictionary —— so it's misleading to even point it out — and instead you must always remove the existing pair and replace them with another. – martineau Oct 18 '20 at 21:03
  • That's an improvement, but you still don't seem to grasp the fact that the keys being tuples has no real bearing on the problem (i.e. that it would still exist if the keys were, for example, strings). Your code works because it's doing the replacement I mention needing to do earlier. – martineau Oct 18 '20 at 21:15
  • I do understand dictionary keys are immutable and I am not saying that tuples are creating problem here. I hope you have seen this "You can replace the keys to achieve". – Shakeel Oct 18 '20 at 21:21
  • Then why even mention it? You might as well add "the sky is blue"… – martineau Oct 18 '20 at 21:23