加入一个dicts列表

时间:2012-05-28 18:24:42

标签: python list sorting dictionary union

我有一些像这样的词典:

list1 = [
    dict(RL = 'rl1', 
        shaders = [dict(shader = "shader1", geom = ['a1','b1']),
        dict(shader = "shader2", geom = ['a2','b2'])]),
    dict(RL = 'rl3', 
        shaders = [dict(shader = "shader1", geom = ['c','d']),...])     
]
list2 = [
    dict(RL = 'rl1', 
        shaders = [dict(shader = "shader1", geom = ['p1','q1']),
        dict(shader = "shader3", geom = ['p3','q3'])]),
    dict(RL = 'rl2', 
        shaders = [dict(shader = "shader1", geom = ['c','d']),...])     
]

所以这是一个dicts列表,其中每个dict都有一个包含dicts列表的值。 我知道它不是最好的数据结构,但现在改变它会非常耗费时间。我想通过它们的RL值加入所有这些列表,然后如果着色器值相同,则将geom列表连接在一起。 因此,例如对于上面的列表,假设只有我写下的条目,我会得到我的新列表与相同的渲染层rl1,相同的着色器shader1,并且geom将是['a','b','c','d'] 谢谢你的帮助

编辑:承认我可以改变这种糟糕的数据结构,我应该使用什么样的结构来让事情变得更容易?我唯一想要的是保持层次结构:一个RL可以包含许多可以包含许多geom的着色器,我可以有很多这样的条目。

1 个答案:

答案 0 :(得分:0)

坚持使用您的数据结构,我得到了这个......

list1 = [dict(RL = 'rl1', shaders = [dict(shader = "shader1", geom = ['a','b']),
                                     dict(shader = "shader3", geom = ['q','p'])])]
list2 = [dict(RL = 'rl1', shaders = [dict(shader = "shader1", geom = ['c','d']),
                                     dict(shader = "shader3", geom = ['x','y'])])]
list3 = [dict(RL = 'rl1', shaders = [dict(shader = "shader2", geom = ['e','f'])])]
list4 = [dict(RL = 'rl2', shaders = [dict(shader = "shader2", geom = ['g','h'])])]
list5 = [dict(RL = 'rl2', shaders = [dict(shader = "shader2", geom = ['i','j'])]),
         dict(RL = 'rl3', shaders = [dict(shader = "shader4", geom = ['ab','cd'])])]

list_o_lists = [list1, list2, list3, list4, list5]

big_list_o_dicts = []
for x in list_o_lists:
    big_list_o_dicts.extend(x)

big_list_o_dicts.sort(key=lambda x: x['RL'])

new_list_o_lists = []

last_item = None
for item in big_list_o_dicts:
    if last_item and item['RL'] == last_item['RL']:
        for this_shader in item['shaders']:
            for last_shader in last_item['shaders']:
                if last_shader['shader'] == this_shader['shader']:
                    last_shader['geom'].extend(this_shader['geom'])
                    break
    else:
        last_item = item
        new_list_o_lists.append(last_item)

它看起来很疯狂,肯定会有更有效的方法,但也许它会帮助你。

编辑:为了响应您的编辑,除非有理由将所有这些列表分开,否则您最终希望将它们全部组合在一起表明维护您想要的结构会更容易一开始。

像...一样的东西。

rl_shader_map = {
    'rl1': {
        'shader1': ['a', 'b', 'c', 'd'],
        'shader2': ['e', 'f'],
    },
    'rl2': {
        'shader2': ['g', 'h', 'i', 'j']
    }
}

更容易检查渲染层中的着色器(而不是迭代,它是哈希表查找)。

每当你创建一个全新的列表对象时,只需在上面的地图中附加或创建适当的频道。

如果您需要为每个着色器维护的信息不仅仅是"geom",那么我会转到另一个类似的词典......

rl_shader_map = {
    'rl1': {
        'shader1': {
            'geom': ['a', 'b', 'c', 'd'],
        }
        'shader2': {
            'geom': ['e', 'f'],
        }
    },
    'rl2': {
        'shader2': {
            'geom': ['g', 'h', 'i', 'j'],
        }
    }
}

另外,作为一个样式点,使用kwarg dict创建是非常未使用的AFAIK,所以我会传递一个可重复的键值元组,如dict([('RL', 'rl1'), ('shader', 'shader1')])或使用{}语法,因为我'已完成。

哇...哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇