Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python3 dictionary values being overwritten

I’m having a problem with a dictionary. I"m using Python3. I’m sure there’s something easy that I’m just not seeing.

I’m reading lines from a file to create a dictionary. The first 3 characters of each line are used as keys (they are unique). From there, I create a list from the information in the rest of the line. Each 4 characters make up a member of the list. Once I’ve created the list, I write to the directory with the list being the value and the first three characters of the line being the key.

The problem is, each time I add a new key:value pair to the dictionary, it seems to overlay (or update) the values in the previously written dictionary entries. The keys are fine, just the values are changed. So, in the end, all of the keys have a value equivalent to the list made from the last line in the file.

I hope this is clear. Any thoughts would be greatly appreciated.

A snippet of the code is below

formatDict = dict()  
sectionList = list()  
for usableLine in formatFileHandle:  
    lineLen = len(usableLine)  
    section = usableLine[:3]  
    x = 3  
    sectionList.clear()  
    while x < lineLen:  
        sectionList.append(usableLine[x:x+4])  
        x += 4
    formatDict[section] = sectionList  
for k, v in formatDict.items():  
    print ("for key= ", k, "value =", v)  
formatFileHandle.close()  
like image 805
Bill Morgan Avatar asked Feb 25 '26 23:02

Bill Morgan


1 Answers

You always clear, then append and then insert the same sectionList, that's why it always overwrites the entries - because you told the program it should.

Always remember: In Python assignment never makes a copy!

Simple fix

Just insert a copy:

formatDict[section] = sectionList.copy()    # changed here

Instead of inserting a reference:

formatDict[section] = sectionList  

Complicated fix

There are lots of things going on and you could make it "better" by using functions for subtasks like the grouping, also files should be opened with with so that the file is closed automatically even if an exception occurs and while loops where the end is known should be avoided.

Personally I would use code like this:

def groups(seq, width):
    """Group a sequence (seq) into width-sized blocks. The last block may be shorter."""
    length = len(seq)
    for i in range(0, length, width):   # range supports a step argument!
        yield seq[i:i+width]

# Printing the dictionary could be useful in other places as well -> so
# I also created a function for this.
def print_dict_line_by_line(dct):  
    """Print dictionary where each key-value pair is on one line."""
    for key, value in dct.items():
        print("for key =", key, "value =", value)

def mytask(filename):
    formatDict = {}
    with open(filename) as formatFileHandle:
        # I don't "strip" each line (remove leading and trailing whitespaces/newlines)
        # but if you need that you could also use:
        # for usableLine in (line.strip() for line in formatFileHandle):
        # instead.
        for usableLine in formatFileHandle:
            section = usableLine[:3]
            sectionList = list(groups(usableLine[3:]))
            formatDict[section] = sectionList
    # upon exiting the "with" scope the file is closed automatically!
    print_dict_line_by_line(formatDict)

if __name__ == '__main__':
    mytask('insert your filename here')
like image 61
MSeifert Avatar answered Feb 28 '26 13:02

MSeifert



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!