osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

How to multiply dictionary values with other values based on the dictionary's key?


On Sunday, August 19, 2018 at 3:53:39 AM UTC+2, Steven D'Aprano wrote:

> 
> Unless you edit your code with Photoshop, why do you think a JPEG is a 
> good idea?
> 
> That discriminates against the blind and visually impaired, who can use 
> screen-readers with text but can't easily read text inside images, and 
> those who have access to email but not imgur.

Thank you very much for the answer Steven! To be honest I did not think of that, I just assumed that it was easier for everyone to just look at the jpeg and see my dictionary. I will keep it in mind for the future.


> Sounds like you have to parse the key for the number fields:
> 
> - extract out the part between the parentheses '0,_0,_2,_2'
> 
> If you know absolutely for sure that the key format is ALWAYS going to be 
> 'FEq_(<fields>)' then you can extract the fields using slicing, like this:
> 
>   key = 'FEq_(0,_0,_2,_2)'
>   fields = key[5, -1]  # cut from char 5 to 1 back from the end
> 
> If you're concerned about that "char 5" part, it isn't an error. Python 
> starts counting from 0, not 1, so char 1 is "E" not "F".
> 
> 
> 
> - delete any underscores
> - split it on commas
> - convert each field to int
> - convert the list of fields to a tuple
> 
>   fields = fields.replace('_', '')
>   fields = string.split(',)
>   fields = tuple([int(x) for x in fields])
> 
> 
> and then you can use that tuple as the key for A.

When I try to this, I get the message 'fields = key[5, -1]. TypeError: string indices must be integers'.

> It might be easier and/or faster to convert A to use string keys 
> "FEq_(0,_0,_2,_2)" instead. Or, depending on the size of A, simply make a 
> copy:
> 
>     B = {}
>     for (key, value) in A.items():
>         B['FEq(%d,_%d,_%d,_%d)' % key] = value
> 
> 
> and then do your look ups in B rather than A.

This helped me a lot! Now I have 2 dictionaries that contain the same keys and the different values I want to multiply, varsdict and B. However if I try to multiply them using:

{k : v * varsdict[k] for k, v in B.items() if k in varsdict}

or

for key in varsdict:
    if key in B:
        print(int(varsdict[key]) * int(B[key]))

all I get is an empty dictionary. Do you know how to make this work?


> I don't see why the dictionary lookup won't work just because the indexes 
> aren't consistent. When you look up 
> 
>     varsdict['FEq_(0,_0,_2,_2)']
> 
> it has no way of knowing whether or not 'FEq_(0,_0,_1,_2)' previously 
> existed. I think you need to explain more of what you are doing rather 
> than just dropping hints.
> 
> *Ah, the penny drops* ...
> 
> 
> Are you trying to generate the keys by using nested loops?
> 
> for i in range(1000):  # up to some maximum value
>     for j in range(1000):
>         for k in range(1000):
>             for l in range(1000):
>                 key = "FEq_({0},_{1},_{2},_{3})".format(i,j,k,l)
>                 value = varsdict[key]  # this fails
> 
> 
> That's going to be spectacularly wasteful if the majority of keys don't 
> exist. Rather, you should just iterate over the ones that *do* exist:
> 
> for key in varsdict:
>     ...

The varsdict dictionary was the result of the optimization run in PulP and contains the 'prob.variables()' keys and values. so while my initial problem variables were created for all i,j,k,l that I wanted, only the 5 appear in the optimization results. 

Now, however I want to multiply the result variables with external dictionary values that were also created for all the  i,j,k,l that I wanted. My B dictionary has a length of 150 but I only want the 5 values with the same keys as the varsdict dictionary to be multiplied with the values in the varsdict dictionary correspondigly.

For 5 key/value pairs I can do it manually but for a more complex problem with hundreds of key/value pairs it will be impossible so I am looking to automate that.

Sorry if that reads confusingly, I just started with python and I am trying to explain as clear as I can.