如何将集合中的元素与多个dict条目相关联

时间:2014-06-16 04:07:46

标签: python xml dictionary dataset set

我正在从XML文件中提取三个元素的实例:ComponentStr,keyID和valueStr。每当我找到ComponentStr时,我想将keyID:valueStr添加/关联到它。 ComponentStr值不是唯一的。当读取多次出现的ComponentStr时,我想为该ComponentStr组累积keyID:valueStr。读取XML文件后生成的累积数据结构可能如下所示:

ComponentA:key1:value1,key2:value2,key3:value3

ComponentB:key4:value4

ComponentC:key5:value5,key6:value6

在生成最终数据结构之后,我想对每个ComponentStr中的keyID:valueStr条目进行排序,并对所有ComponentStrs进行排序。

我正在尝试在Python 2中构建这些数据.ComponentStr似乎可以很好地作为一个集合。 keyID:valueStr显然是一个字典。但是如何将集合中的ComponentStr条目与其dict条目相关联?

或者,除了集合和相关的dict条目之外,还有更好的方法来组织这些数据吗?每个keyID都是唯一的。也许我可以有一个keyID的dict:ComponentStr和valueStr的一些组合?在构建数据结构之后,我可以先基于ComponentStr对其进行排序,然后执行某种类型的切片来对keyID:valueStr进行分组,然后再对keyID进行排序?似乎很复杂。

2 个答案:

答案 0 :(得分:2)

dicts的词典怎么样?

data = {
'ComponentA': {'key1':'value1', 'key2':'value2', 'key3':'value3'},
'ComponentB': {'key4':'value4'},
'ComponentC': {'key5':'value5', 'key6':'value6'},
}

它维护您的数据结构和映射。有趣的是,dicts的底层实现类似于集合的实现。

这很容易构造成一个伪代码:

data = {}
for file in files:
    data[get_component(file)] = {}
    for key, value in get_data(file):
        data[get_component(file)][key] = value

如果你有重复的组件,你需要将sub-dict作为默认值,但如果它在那里则添加到前一个。我更喜欢setdefault到其他解决方案,例如defaultdict或子类化带有__missing__的dict,只要我只需要在代码中执行一次或两次:

data = {}
for file in files:
    for key, value in get_data(file):
        data.setdefault([get_component(file)], {})[key] = value

它的工作原理如下:

>>> d = {}
>>> d.setdefault('foo', {})['bar'] = 'baz'
>>> d
{'foo': {'bar': 'baz'}}
>>> d.setdefault('foo', {})['ni'] = 'ichi'
>>> d
{'foo': {'ni': 'ichi', 'bar': 'baz'}}

另外,当我读到你对其他答案的评论说你需要简单的代码时,你可以通过一些更冗长和更少优化的代码来保持简单:

data = {}
for file in files:
    for key, value in get_data(file):
        if get_component(file) not in data:
            data[get_component(file)] = {}
        data[get_component(file)][key] = value

然后,您可以在收集完数据后进行排序。

for component in sorted(data):
    print(component)
    print('-----')
    for key in sorted(data[component]):
        print(key, data[component][key])

答案 1 :(得分:1)

  

我想累积该ComponentStr组的keyID:valueStr

在这种情况下,您希望将词典中的键作为ComponentStr,立即累积到列表中,这些列表很容易订购。

  

每个keyID都是唯一的。也许我可以有一个关键字ID:一些   ComponentStr和valueStr的组合?

您应该以想要检索数据的最有效方式存储数据。由于您将通过组件访问您的数据,即使您的密钥是唯一的,也没有必要使用您的密钥访问的字典(因为这不是您要“检索”数据的方式)。

那么,有了这个 - 如何将defaultdict与列表一起使用,因为你真的想要所有与同一组件相关联的项目:

from collections import defaultdict

d = defaultdict(list)

with open('somefile.xml', 'r') as f:
   for component, key, value in parse_xml(f):
       d[component].append((key, value))

现在,每个组件都有一个元组列表,它们是关联的键和值。

如果要按照从文件中读取组件的顺序保留组件,可以使用OrderedDict(也来自collections module),但是如果要在任何组件中对它们进行排序任意顺序,然后坚持正常的字典。

要获取已排序组件名称的列表,只需对字典的键进行排序:

component_sorted = sorted(d.keys())

对于打印已排序组件及其关联键/值对的用例,按键分类:

for key in component_sorted:
   values = d[key]
   sorted_values = sorted(values, key=lamdba x: x[0])  # Sort by the keys
   print('Pairs for {}'.format(key))
   for k,v in sorted_values:
       print('{} {}'.format(k,v))