dict.setdefault将一个额外的(默认?)项附加到值列表中

时间:2016-03-10 14:11:41

标签: python dictionary setdefault

我正在使用字典对CSV文件中的数据进行分组,因此例如第一列和第二列是dict键,值将是第3,4列的元组列表。

我的代码段是:

import csv
import collections
csvDicData_ = dict()

fh = open('myfile.csv', 'rt')
reader = csv.reader(fh, delimiter=';', skipinitialspace=True)
for indx, row in enumerate(reader):
    if row:
        #-- put in a dictionary form: #csvDicData_[(row[0],row[1])] = (row[2],row[3])
        key   = (row[0],row[1])
        value = (row[2],row[3])
        #-- I'd like to use the row below (commented) insted of the next two, I expect the same result... 
        #csvDicData_.setdefault(key,[value]).append(value)

        if (not key in csvDicData_): csvDicData_[key] = [value]
        else: csvDicData_[key].append(value)

上面的代码生成了正确的结果,尽管我尝试使用csvDicData_.setdefault(key,[value]).append(value),由于某种原因我不明白,len(csvDicData_[('field1x','field2x')] ))总是还有一个项目(值为(0,0))预期的。

为什么会出现这种情况(就像每个键的CSV文件中的第一行自动将元组(0,0)添加到字典/键中。

2 个答案:

答案 0 :(得分:2)

当你这样做时

csvDicData_.setdefault(key,[value]).append(value)

您将列表初始化为[value](如果缺少),然后将value添加到其中,并为您提供[value, value]。你想要的是用空列表初始化:

csvDicData_.setdefault(key,[]).append(value)

或使用collections.defaultdict(list),然后执行

csvDicData_[key].append(value)

答案 1 :(得分:2)

你第一次这样做

csvDicData_.setdefault(key,[value]).append(value)

key将不在字典中,因此将使用值[value]创建密钥。现在,setdefault返回与key对应的值。因此,系统会返回[value],您将value附加到其中。这就是为什么你总是得到一个额外的元素。

这应该只是

csvDicData_.setdefault(key, []).append(value)

现在,将返回空列表,您将向其附加value

除此之外,您可能希望使用with语句打开文件,如此

with open('myfile.csv', 'rt') as fh:
    reader = csv.reader(fh, delimiter=';', skipinitialspace=True)
    for indx, row in enumerate(reader):
        ....

这样您就不必担心明确关闭文件了。