在保留字典的同时将dict值转换为集合

时间:2012-11-08 17:31:14

标签: python dictionary set

我有这样的字典:

(100002:'APPLE',100004:'BANANA',100005:'CARROT')

我试图使我的dict有关键的内容(就像现在一样)但是有值的设置(而不是现在的字符串。)我的目标是能够从.csv文件中读取一列为键(一个int,即项目ID号),然后是列,用于大小,形状和颜色等。我想将这些信息添加到我的dict中,以便只添加已经存在于dict中的键的信息。

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

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

从我的项目名称的密钥+字符串的dict开始,我尝试使用这样的代码从.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'。我尝试将字典的值更改为集合,以便我可以更新它们,这样就产生了这样的结果:(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生成一个列表而不是一个set(以便保留顺序。)我还发现更容易更新。 csv数据输入文件通过将包含名称的列添加到FileWithTheData.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

2 个答案:

答案 0 :(得分: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:])

答案 1 :(得分: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 MyDictkey in MyDict.keys()相同)