Python3字典值被覆盖

时间:2017-08-28 12:31:33

标签: python python-3.x list dictionary

我遇到字典问题。我使用Python3。我确信有一些我不会看到的简单。

我正在从文件中读取行来创建字典。每行的前3个字符用作键(它们是唯一的)。从那里,我从该行的其余部分的信息创建一个列表。每4个字符组成一个列表的成员。一旦我创建了列表,我就会写入目录,其中列表是值,而行的前三个字符是键。

问题是,每次我向字典添加一个新的键:值对时,它似乎覆盖(或更新)先前写入的字典条目中的值。键很好,只是值被更改。因此,最后,所有键的值都等于文件中最后一行的列表。

我希望这很清楚。任何想法都将不胜感激。

代码片段在

之下
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()  

2 个答案:

答案 0 :(得分:4)

你总是清楚,然后追加,然后插入相同的sectionList,这就是为什么它总是覆盖条目 - 因为你告诉程序它应该。

永远记住:在Python作业中,从不制作副本!

简单修复

只需插入副本:

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

而不是插入引用:

formatDict[section] = sectionList  

复杂的修复

有很多事情正在发生,你可以做到更好&#34;通过使用像分组这样的子任务的函数,还应该使用with打开文件,这样即使发生异常也会自动关闭文件,并且应该避免while循环已知结束的位置。

我个人会使用这样的代码:

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')

答案 1 :(得分:1)

您可以通过使用with语句自动关闭文件并将该行的其余部分分成四个一组来简化您的代码,从而避免重复使用单个列表。

from itertools import islice

with open('somefile') as fin:
    stripped = (line.strip() for line in fin)
    format_dict = {
        line[:3]: list(iter(lambda it=iter(line[3:]): ''.join(islice(it, 4)), '')) 
        for line in stripped
    }

for key, value in format_dict.items():
    print('key=', key, 'value=', value)