0

I am trying to traverse through a dictionary and capitalize all of the keys if they are strings. I am getting a RunTime error for this:

for k, v in ref_dict.items():
    if isinstance(k, str):
        ref_dict[k.upper()] = v
    else:
        ref_dict[k] = v

How do I avoid something like this? Or, better, how do I improve the code in order to solve this more elegantly?

sgerbhctim
  • 3,420
  • 7
  • 38
  • 60
  • Possible duplicate of [How to avoid "RuntimeError: dictionary changed size during iteration" error?](https://stackoverflow.com/questions/11941817/how-to-avoid-runtimeerror-dictionary-changed-size-during-iteration-error) – johnchase Feb 10 '19 at 20:08

2 Answers2

1

How big is your dict? If it is not huge, then you could do:

new_dict = {}
for k, v in ref_dict.items():
    if isinstance(k, str):
        new_dict[k.upper()] = v
    else:
        new_dict[k] = v

ref_dict = new_dict

In the other case, you may need to review your creation of ref_dict and modify the key there.

Also, one could modify your original code as follows change ref_dict. But it's worth mentioning that it would add new elements to ref_dict. For example

ref_dict = {'abc' : 1}

### change of code
keys = [k for key in ref_dict]

for k in keys:
    if isinstance(k, str):
        ref_dict[k.upper()] = ref_dict[k]
    # else part is not neccessary
    # else:
    #     ref_dict[k] = v

# now ref_dict = {'abc':1, 'ABC':1}
Quang Hoang
  • 146,074
  • 10
  • 56
  • 74
0

I solved it by doing this:

final_dict = dict((str(k).upper(), v) for k, v in ref_dict.items())
return final_dict

The str application is not ideal, but it will do for now.

sgerbhctim
  • 3,420
  • 7
  • 38
  • 60
  • 1
    This is essentially my suggestion in better python style. You can do `final_dict = dict((k.upper(), v) if isinstance(k, str) else (k,v) for k, v in ref_dict.items())`. – Quang Hoang Feb 10 '19 at 20:11
  • @QuangHoang beautiful. This is perfect! Thanks a bunch. – sgerbhctim Feb 10 '19 at 20:14