3

我有一个这样的字典:

(100002:“苹果”,100004:“香蕉”,100005:“胡萝卜”)

我正在尝试使我的 dict 具有键的整数(就像现在一样),但具有值的集合(而不是现在的字符串。)我的目标是能够从 .csv 文件中读取一列键(一个int,它是项目ID号),然后是大小、形状和颜色等列。我想将此信息添加到我的字典中,以便仅添加字典中已有键的信息。

我的目标字典可能如下所示:

(100002: set(['APPLE','MEDIUM','ROUND','RED']), 100004: set(['Banana','MEDIUM','LONG','YELLOW']), 100005: set(['CARROT','MEDIUM','LONG','ORANGE'])

从我的项目名称的键 + 字符串开始,我尝试使用这样的代码从 .csv 文件中读取额外信息:

infile = open('FileWithTheData.csv', 'r')
for line in infile.readlines():
    spl_line = line.split(',')
    if int(spl_line[0]) in MyDict.keys():
        MyDict[int(spl_line[0])].update(spl_line[1:])

不幸的是,这个错误说出来了AttributeError: 'str' object has no attribute 'update'。我尝试将字典的值更改为集合,以便我可以 .update 它们产生如下结果:(100002: set(['A','P','L','E']), 100004: set(['B','A','N']), 100005: set(['C','A','R','O','T'])) 我想将值转换为集合,以便当前值的字符串将成为集合中的第一个字符串而不是而不是将字符串分解成字母并制作一组这些字母。

当我通过将两个列表压缩在一起来创建字典时,我还尝试将这些值设置为一组,但它似乎没有任何区别。像这样的东西 MyDict = dict(zip(listofkeys, set(listofnames))) 仍然使整个 listofnames 列表成为一个集合,但它没有实现我的目标,即使 MyDict 中的每个值与 listofnames 中的相应字符串成一个集合为集合中的第一个字符串。

如何将 MyDict 中的值设置为一个集合,以便我可以向该集合添加其他字符串,而无需将当前作为 dict 中值的字符串转换为一组单独的字母?

编辑:我目前通过使用一个函数生成项目ID列表(它们是键)和另一个查找这些项目ID以生成相应项目名称列表的函数来制作MyDict(使用两列.csv文件作为数据源)然后我zip将它们放在一起。

回答:使用这里的建议,我想出了这个解决方案。我发现有 set()).update 的部分可以很容易地更改为 list()).append 以产生一个列表而不是一个集合(以便保留顺序。)我还发现通过 .通过将包含名称的列添加到 FileWithTheData.csv 来创建 csv 数据输入文件,这样我就不必费心制作 dict,将值转换为集合,然后添加更多数据。我本节的代码现在如下所示:

MyDict = {}
infile = open('FileWithTheData.csv', 'r')
for line in infile.readlines():
    spl_line = line.split(',')
    if int(spl_line[0]) in itemidlist: #note that this is the list I was formerly zipping together with a corresponding list of names to make my dict
        MyDict.setdefault(int(spl_line[0]), list()).append(spl_line[1:])
print MyDict
4

2 回答 2

4

您的错误是因为最初您的MyDict变量将整数映射到字符串。当您尝试更新它时,您将值视为set,字符串时的值。

您可以为此使用defaultdict :

combined_dict = defaultdict(set)

# first add all the values from MyDict
for key, value in MyDict.iteritems():
    combined_dict[int(key)].add(value)

# then add the values from the file
infile = open('FileWithTheData.csv', 'r')
for line in infile.readlines():
    spl_line = line.split(',')
    combined_dict[int(sp_line[0])].update(spl_line[1:])
于 2012-11-08T17:34:51.487 回答
2

您的问题在于您的初始化方式MyDict,请尝试将其更改为以下内容:

MyDict = dict(zip(listofkeys, [set([name]) for name in listofnames]))

这是差异的一个简单示例:

>>> listofkeys = [100002, 100004, 100005]
>>> listofnames = ['APPLE', 'BANANA', 'CARROT']
>>> dict(zip(listofkeys, set(listofnames)))
{100002: 'CARROT', 100004: 'APPLE', 100005: 'BANANA'}
>>> dict(zip(listofkeys, [set([name]) for name in listofnames]))
{100002: set(['APPLE']), 100004: set(['BANANA']), 100005: set(['CARROT'])}

set(listofnames)只是要将您的列表变成一个集合,唯一可能产生的效果是重新排序值,如上所示。您实际上想要获取列表中的每个字符串值,并将其转换为一个元素集,这就是列表推导所做的。

进行此更改后,您当前的代码应该可以正常工作,尽管您可以直接对字典进行包含检查,而不是显式检查键(key in MyDict与 相同key in MyDict.keys())。

于 2012-11-08T17:38:17.573 回答