Convert python dictionary to uppercase

12,531

Solution 1

In python 3 you cannot do that:

for k,v in newDict.items():
    newDict.update({k.upper(): v.upper()})

because it changes the dictionary while iterating over it and python doesn't allow that (It doesn't happen with python 2 because items() used to return a copy of the elements as a list). Besides, even if it worked, it would keep the old keys (also: it's very slow to create a dictionary at each iteration...)

Instead, rebuild your dict in a dict comprehension:

newDict = {k.upper():v.upper() for k,v in newDict.items()}

Solution 2

You should not change dictionary items as you iterate over them. The docs state:

Iterating views while adding or deleting entries in the dictionary may raise a RuntimeError or fail to iterate over all entries.

One way to update your dictionary as required is to pop values and reassign in a for loop. For example:

d = {'abc': 'xyz', 'def': 'uvw', 'ghi': 'rst'}

for k, v in d.items():
    d[k.upper()] = d.pop(k).upper()

print(d)

{'ABC': 'XYZ', 'DEF': 'UVW', 'GHI': 'RST'}

An alternative is a dictionary comprehension, as shown by @Jean-FrançoisFabre.

Share:
12,531
Admin
Author by

Admin

Updated on June 25, 2022

Comments

  • Admin
    Admin almost 2 years

    For some reason my code refuses to convert to uppercase and I cant figure out why. Im trying to then write the dictionary to a file with the uppercase dictionary values being inputted into a sort of template file.

    #!/usr/bin/env python3
    import fileinput
    from collections import Counter
    
    
    #take every word from a file and put into dictionary
    newDict = {}
    dict2 = {}
    with open('words.txt', 'r') as f:
            for line in f:
                k,v = line.strip().split(' ')
                newDict[k.strip()] = v.strip()
    print(newDict)
    choice = input('Enter 1 for all uppercase keys or 2 for all lowercase, 3 for capitalized case or 0 for unchanged \n')
    print("Your choice was " + choice)
    
    if choice == 1:
        for k,v in newDict.items():
            newDict.update({k.upper(): v.upper()})
    if choice == 2:
        for k,v in newDict.items():
            dict2.update({k.lower(): v})
    
    
    #find keys and replace with word
    
    print(newDict)
    with open("tester.txt", "rt") as fin:
        with open("outwords.txt", "wt") as fout:
            for line in fin:
                fout.write(line.replace('{PETNAME}', str(newDict['PETNAME:'])))
                fout.write(line.replace('{ACTIVITY}', str(newDict['ACTIVITY:'])))
    
    myfile = open("outwords.txt")
    txt = myfile.read()
    print(txt)
    myfile.close()
    
  • Soren V. Raben
    Soren V. Raben over 2 years
    Why newDict} is not sufficient? I tried your solution and it of course works but I'm just curious why version without .items() doesn't work.
  • Jean-François Fabre
    Jean-François Fabre over 2 years
    because with just newDict the loop iterates on the keys, not the key/value tuples
  • Soren V. Raben
    Soren V. Raben over 2 years
    Okay, so I guess it's because myDict.keys() is only for keys, myDict.values() is only for values and myDict.items() is for key/value tuples? By the way - is it possible to uppercase dictionary keys without looping?
  • Jean-François Fabre
    Jean-François Fabre over 2 years
    @Konrad exactly. .keys() is really not super useful as iterating/testing on myDict has the same effect. For "is it possible to uppercase dictionary keys without looping?" => you have to apply upper() on each key so the answer is no.