5

There is a dict params:

{'channel': 'DIMENSION',
 'day': 'DIMENSION',
 'subscribersGained': 'METRIC',
 'likes': 'METRIC',
 'views': 'METRIC',
 'subscribersLost': 'METRIC'}

What I want to do is if value == 'DIMENSION', change its name to 'element_n', where n is the key's position.

So my desired output is

{'element_1': 'DIMENSION',
 'element_2': 'DIMENSION',
 'subscribersGained': 'METRIC',
 'likes': 'METRIC',
 'views': 'METRIC',
 'subscribersLost': 'METRIC'}

So far I did it

for k,v in params.items():
    if v == 'DIMENSION':
        v=['element_{}'.format(i+1) for i in range(len(params.values()))]

But it doesn't change anything

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Anna
  • 914
  • 9
  • 25
  • 2
    Possible duplicate of [Rename a dictionary key](https://stackoverflow.com/questions/16475384/rename-a-dictionary-key) – Mike Scotty Sep 17 '19 at 09:09
  • 1
    Think about that code a minute. If v is dimension, you want to then set v to a list of strings? Maybe you meant to try to set k instead? – OneCricketeer Sep 17 '19 at 09:15

4 Answers4

6

You could instead build the dictionary anew with the following dictionary comprehension with enumerate to format the key with the corresponding index:

{k if v != 'DIMENSION' else 'element_{}'.format(i):v  for i,(k,v) in enumerate(d.items())}

{'element_0': 'DIMENSION',
 'element_1': 'DIMENSION',
 'likes': 'METRIC',
 'subscribersGained': 'METRIC',
 'subscribersLost': 'METRIC',
 'views': 'METRIC'}

Input data -

d = {'channel': 'DIMENSION',
 'day': 'DIMENSION',
 'subscribersGained': 'METRIC',
 'likes': 'METRIC',
 'views': 'METRIC',
 'subscribersLost': 'METRIC'}
yatu
  • 86,083
  • 12
  • 84
  • 139
  • 2
    I'm getting the correct output @anna the one I've shared (just double checked) – yatu Sep 17 '19 at 09:15
  • 1
    If the sample data is not good enough to generalise, please share a more representative sample @AnnaDmitrieva – yatu Sep 17 '19 at 09:18
3

You can do it with a one-liner:

{(v == 'DIMENSION' and 'element_{}'.format(i) or k):v for i, (k, v) in  enumerate(d.items(), 1)}
FabioL
  • 932
  • 6
  • 22
2

Try this:

x = {'channel': 'DIMENSION',
     'day': 'DIMENSION',
     'subscribersGained': 'METRIC',
     'likes': 'METRIC',
     'views': 'METRIC',
     'subscribersLost': 'METRIC'}


index = 1
x_ = {}
for k, v in x.items():
    if v == 'DIMENSION':
        k = "element_{}".format(index)
        index += 1
    x_[k] = v

print(x_)

output:

 {'subscribersLost': 'METRIC', 'views': 'METRIC', 'element_1': 'DIMENSION', 'element_2': 'DIMENSION', 'likes': 'METRIC', 'subscribersGained': 'METRIC'}

I didn't use enumerate because it can generate, element_1, element_4 if the items are in sequential positions(Order is not guaranteed in dictionary):

{....'element_1': 'DIMENSION', `'element_4': 'DIMENSION'.....}`
Charif DZ
  • 14,415
  • 3
  • 21
  • 40
2

you can create new dictionary using list comprehension, I defined lambda function to make the comprehension clean and readable

d = {'channel': 'DIMENSION',
 'day': 'DIMENSION',
 'subscribersGained': 'METRIC',
 'likes': 'METRIC',
 'views': 'METRIC',
 'subscribersLost': 'METRIC'}


## solution

get_key = lambda key, value, indx: f"element_{indx+1}" if value == "DIMENSION" else key

{get_key(key, value, i): value for i, (key, value) in enumerate(d.items())}

Dev Khadka
  • 5,142
  • 4
  • 19
  • 33