Changing specific values in a python dictionary

Question:

I have the following dictionary in python:

dict={('M1 ', 'V1'): 5,
 ('M1 ', 'V2'): 5,
 ('M1 ', 'V3'): 5,
 ('M1 ', 'V4'): 5,
 ('M2', 'V1'): 5,
 ('M2', 'V2'): 5,
 ('M2', 'V3'): 5,
 ('M2', 'V4'): 5,
 ('M3', 'V1'): 5,
 ('M3', 'V2'): 5,
 ('M3', 'V3'): 5,
 ('M3', 'V4'): 5}

For contextualization, "dict" is a matrix distance ((‘Source’, ‘Destination’): Value) for an optimization problem, and in conducting a sensitivity analysis, I want to make the distances from M1 so high that the model won’t choose it. Therefore, I want to get the python code to change the value of each line where M1 is a source.

Asked By: Bree

||

Answers:

What you are doing here is you want to filter dictionary keys based on a value. the keys here are of tuple type. so basically you need to iterate the keys and check if they have the needed value.

#let's get a list of your keys first
l = []   #a placeholder for the dict keys that has 'M1' in source
for k in dict.keys():   # iterate the keys
   if k[0].strip() == 'M1':     # 'M1' in the source node, strip to remove whitespaces if found
       l.append(k)      # a list of the keys that has 'M1' as a source
Answered By: Ahmed Sayed

There’s no way to directly access the items where part of the key tuple is M1. You will need to loop through.

d={
     ('M1', 'V1'): 5,
     ('M1', 'V2'): 5,
     ('M1', 'V3'): 5,
     ('M1', 'V4'): 5,
     ('M2', 'V1'): 5,
     ('M2', 'V2'): 5,
     ('M2', 'V3'): 5,
     ('M2', 'V4'): 5,
     ('M3', 'V1'): 5,
     ('M3', 'V2'): 5,
     ('M3', 'V3'): 5,
     ('M3', 'V4'): 5
}

for source, dest in d:
    if source == 'M1':
        d[(source, dest)] *= 10000
  

This will change d in-place to:

{('M1', 'V1'): 50000,
 ('M1', 'V2'): 50000,
 ('M1', 'V3'): 50000,
 ('M1', 'V4'): 50000,
 ('M2', 'V1'): 5,
 ('M2', 'V2'): 5,
 ('M2', 'V3'): 5,
 ('M2', 'V4'): 5,
 ('M3', 'V1'): 5,
 ('M3', 'V2'): 5,
 ('M3', 'V3'): 5,
 ('M3', 'V4'): 5}

Also, I’m assuming the key "M1 " with a space is a typo. I’ve changed that to "M1", above. Adjust as required.

Answered By: Mark

First off, dict is a reserved keyword, so don’t use that as the name of your dictionary.

distances = {(...): ...,}

for source, destination in distances:
    if source == "M1 ":
        distances[(source, destination)] = 100000 # or something

Answered By: Dash

        f  = lambda src, dist : (dist * 100) if (src == 'M1 ')  else dist
        new_dict = {(src, dst): f(src, v) for (src, dst), v in dict.items()}

I don’t love using python comprehensions for complex code (personally I think .map() function calls are more readable, but this works. It has the benefit of being pure functional – no values are actually mutated, so you can preserve the original for use elsewhere if you so wish.

Answered By: Edward Peters
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.