0

So I have the below dict

dict = {'tma_prot_{}.grnh':[r'$T_n-P_h$'], 'tma_prot_{}.groh':[r'$T_o-P_h$'], 'tma_urea_{}.grcn':[r'$T_c-U_n$'],
        'tma_urea_{}.gron':[r'$T_o-U_n$'], 'tma_wat_{}.grco':[r'$T_c-W_o$']}

So instead of tma_prot_0.grnh I want 0 to be changed to any number eg: tma_prot_2.grnh

this value I get from say l1 = [0, 2, 11]

so when I call

dict["tma_prot_11.grnh"] or dict["tma_prot_2.grnh"]

I should get value of tma_prot_0.grnh which is

[r'$T_n-P_h$']

I want a generalized dictionary.

My attempt

for i in l1:
    for key in dict.keys():
        dict["key".format(l1[i])] = dict["key"]
ComplicatedPhenomenon
  • 4,055
  • 2
  • 18
  • 45
WhySoSerious
  • 185
  • 1
  • 19

4 Answers4

2

No straightforward way to achieve this. Other answers attempt to rename the keys or add new keys.

My solution seems more complex, but it is quite simple. It creates a custom dict that modifies the key that it gets rather than the dictionary keys.

import re
from collections import UserDict

class MyDict(UserDict):
    digit_regex = re.compile(r'(\d+)')

    def __getitem__(self, item):
        new_key = self.digit_regex.sub('0', item)
        return super().__getitem__(new_key)

d = MyDict({'tma_prot_0.grnh': [r'$T_n-P_h$'], 'tma_prot_0.groh': [r'$T_o-P_h$'],
            'tma_urea_0.grcn': [r'$T_c-U_n$'], 'tma_urea_0.gron': [r'$T_o-U_n$'],
            'tma_wat_0.grco': [r'$T_c-W_o$']})

for i in [0, 2, 11]:
    print(d['tma_prot_{}.grnh'.format(i)])

Outputs

['$T_n-P_h$']
['$T_n-P_h$']
['$T_n-P_h$']
DeepSpace
  • 78,697
  • 11
  • 109
  • 154
1

You are almost there:

for i in l1:
    for key in list(dict.keys()):
        dict[key.format(i)] = dict[key]
ilmiacs
  • 2,566
  • 15
  • 20
  • this gives `RuntimeError: dictionary changed size during iteration` – WhySoSerious Sep 03 '19 at 14:07
  • Adjusted the answer, the error should have gone away. (Background: in Python3 `dict.keys()` gives an iterator and does not evaluate. You can force it by requesting a `list`.) – ilmiacs Sep 03 '19 at 14:11
  • @WhySoSerious In the above code there is no list element access operation, so it can not produce a «list index out of range» error. Either the error comes from a differen part of your code or your comment relates to another answer but not this one. – ilmiacs Sep 04 '19 at 07:32
1

Just use a new dict to store the instanced content:


template_dict = {'tma_prot_{}.grnh':[r'$T_n-P_h$'], 'tma_prot_{}.groh':[r'$T_o-P_h$'], 'tma_urea_{}.grcn':[r'$T_c-U_n$'],
        'tma_urea_{}.gron':[r'$T_o-U_n$'], 'tma_wat_{}.grco':[r'$T_c-W_o$']}

dict = {}
l1 = [0, 2, 11]

for i in l1:
    for key in template_dict:
        dict[key.format(i)] = template_dict[key]

Then you can use the dict to handle your requirement.

Fogmoon
  • 569
  • 5
  • 16
0

Have you tried just adding a key, value pair to your dictionary for every number you need? For example:

value = dict["tma_prot_0.grnh"]
for number in l1:
    new_key = "tma_prot_{}.grnh".format(str(number))
    dict[new_key] = value

When I get you right you want to have the value available for every number in l1 but either way you can access it for only one number per entry regardless of how you named the key

Karl K.
  • 3
  • 1