[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 Sat, 18 Aug 2018 16:16:54 -0700, giannis.dafnomilis wrote:

> I have the results of an optimization run in the form found in the
> following pic: https://i.stack.imgur.com/pIA7i.jpg.

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.

For the record, here's the table:

Key			Type	Size	Value
FEq_(0,_0,_0,_0)	float	1	1.0
FEq_(0,_0,_1,_1)	float	1	1.0
FEq_(0,_0,_2,_2)	float	1	1.0
FEq_(0,_0,_3,_0)	float	1	1.0
FEq_(0,_0,_4,_1)	float	1	1.0

It took me about 30 seconds to copy out by hand from the image. But what 
it means is a complete mystery. Optimization of what? What you show isn't 
either Python code or a Python object (like a dict or list) so it isn't 
any value to us.

> How can I multiply the dictionary values of the keys FEq_(i,_j,_k,_l)
> with preexisting values of the form A[i,j,k,l]?
> For example I want the value of key 'FEq_(0,_0,_2,_2)' multiplied with
> A[0,0,2,2], the value of key 'FEq_(0,_0,_4,_1)' multiplied with
> A[0,0,4,1] etc. for all the keys present in my specific dictionary.

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.

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 

    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.

> I have been trying to correspondingly multiply the dictionary values in
> the form of
>     varsdict["FEq_({0},_{1},_{2},_{3})".format(i,j,k,l)]
> but this is not working as the indexes do not iterate consequently over
> all their initial range values, they are the results of the optimization
> so some elements are missing.

I don't see why the dictionary lookup won't work just because the indexes 
aren't consistent. When you look up 


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:

Steven D'Aprano
"Ever since I learned about confirmation bias, I've been seeing
it everywhere." -- Jon Ronson