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

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sat Aug 18 21:51:01 EDT 2018


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 
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.


> 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 

    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:
    ...



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




More information about the Python-list mailing list