使用字典复杂的引用,python

时间:2015-08-25 14:31:00

标签: python dictionary lookup

假设我有两个字典如下:

vertices_on_tetrahedron = {
    0: [0, 1, 3, 7],
    1: [0, 1, 5, 7],
    2: [0, 4, 5, 7],
    3: [0, 2, 3, 7],
    4: [0, 4, 6, 7],
    5: [0, 2, 6, 7],
}
data_on_tetrahedron = {
    0: [78, 79, 80],
    1: [111, 112, 113],
    2: [144, 145, 146],
    3: [45, 46, 47],
    4: [177, 178, 179],
    5: [201, 202, 203],
}

接下来,我要做的是制作一个这样的字典:

result = {
    0: [78, 79, 80, 111, 112, 113, 144, 145, 146, 45, 46, 47, 177, 178, 179, 201, 202, 203],
    1: [78, 79, 80, 111, 112, 113],
    2: [45, 46, 47, 201, 202, 203],
    3: [78, 79, 80, 45, 46, 47],
    4: [144, 145, 146, 177, 178, 179],
    5: [111, 112, 113, 144, 145, 146],
    6: [177, 178, 179, 201, 202, 203],
    7: [78, 79, 80, 111, 112, 113, 144, 145, 146, 45, 46, 47, 177, 178, 179, 201, 202, 203],
}

这个字典可以如下获得(必须有其他方法)。首先,我需要将dict vertices_on_tetrahedron重新排列为一个临时的:

tets_sharing_vertex = {
    0: [0, 1, 2, 3, 4, 5],
    1: [0, 1],
    2: [3, 5],
    3: [0, 3],
    4: [2, 4],
    5: [1, 2],
    6: [4, 5],
    7: [0, 1, 2, 3, 4, 5]
}

这是一个字典,其中每个键代表字典vertices_on_tetrahedron的值列表中的一个数字,value是具有此数字的字典vertices_on_tetrahedron的键列表。

然后,最终结果是一个字典,其键等于字典tets_sharing_vertex的键,并根据字典b中的值列表从字典tets_sharing_vertex获取值。

我实现如下(我承认非常难看):

def find_tets_sharing_vertex(vertex,input_dict):
    tmp = []
    for k, v in input_dict.iteritems():
        if vertex in v:
            tmp.append(k)

    return tmp

result_lst = []
for vertex in vertices:
    tmp = find_tets_sharing_vertex(vertex, vertices_on_tetrahedron)
    result_lst.append([b[i] for i in tmp])

result_tmp = dict(zip(values,result_lst))
result = {}
for i in range(len(result_tmp)):
    result[i] = flatten(result_tmp[i])

此处,vertices是字典vertices_on_tetrahedron的所有可能值条目的列表。函数flatten()展平列表列表:[[0], [1]] -> [0, 1]

从概念上讲,result_lst解决了问题,但它看起来像这样:

[[[78, 79, 80], [111, 112, 113], [144, 145, 146], [45, 46, 47], [177, 178, 179], [201, 202, 203]], ... ]

这就是我使用result_tmpresult再做一步的原因。

此实现有效,但速度很慢,我实际上需要它来处理大型词典vertices_on_tetrahedrondata_on_tetrahedronvertices_on_tetrahedron的结构始终相同:每个键的值列表不超过4个项目。但可能有成千上万的钥匙。对于vertices_on_tetrahedron,每个值都是一个不超过3个项目的列表。

不幸的是,我收到了vertices_on_tetrahedrondata_on_tetrahedron这种形式,因此我无法重新考虑更改数据结构以避免这种情况。

如果有人也可以推荐一些参考来阅读这类问题,我将非常感激。

4 个答案:

答案 0 :(得分:3)

首先,从tets_sharing_vertex

构建vertices_on_tetrahedron
from pprint import pprint
from collections import defaultdict

tets_sharing_vertex = defaultdict(list)
for k, v in vertices_on_tetrahedron.items():
    for x in v:
        tets_sharing_vertex[x].append(k)

pprint(tets_sharing_vertex)

输出:

{0: [0, 1, 2, 3, 4, 5],
 1: [0, 1],
 2: [3, 5],
 3: [0, 3],
 4: [2, 4],
 5: [1, 2],
 6: [4, 5],
 7: [0, 1, 2, 3, 4, 5]}

其次,从resultdata_on_tetrahedron

获取tets_sharing_vertex
from itertools import chain

result = {k: list(chain.from_iterable(data_on_tetrahedron[x] for x in v)) for k, v in tets_sharing_vertex.items()}

pprint(result, width=100)

输出:

{0: [78, 79, 80, 111, 112, 113, 144, 145, 146, 45, 46, 47, 177, 178, 179, 201, 202, 203],
 1: [78, 79, 80, 111, 112, 113],
 2: [45, 46, 47, 201, 202, 203],
 3: [78, 79, 80, 45, 46, 47],
 4: [144, 145, 146, 177, 178, 179],
 5: [111, 112, 113, 144, 145, 146],
 6: [177, 178, 179, 201, 202, 203],
 7: [78, 79, 80, 111, 112, 113, 144, 145, 146, 45, 46, 47, 177, 178, 179, 201, 202, 203]}

答案 1 :(得分:1)

以下应该比您当前的解决方案快得多:

import collections

result = collections.defaultdict(list)
[result[v2].extend(data_on_tetrahedron[k1]) for k1,v1 in vertices_on_tetrahedron.items() for v2 in v1]

print result

,并提供:

defaultdict(<type 'list'>, {0: [78, 79, 80, 111, 112, 113, 144, 145, 146, 45, 46, 47, 177, 178, 179, 201, 202, 203], 1: [78, 79, 80, 111, 112, 113], 2: [45, 46, 47, 201, 202, 203], 3: [78, 79, 80, 45, 46, 47], 4: [144, 145, 146, 177, 178, 179], 5: [111, 112, 113, 144, 145, 146], 6: [177, 178, 179, 201, 202, 203], 7: [78, 79, 80, 111, 112, 113, 144, 145, 146, 45, 46, 47, 177, 178, 179, 201, 202, 203]})

答案 2 :(得分:0)

我认为这会奏效:

result =dict((i, []) for i in range(8))
for l in vertices_on_tetrahedron.keys():
    for j in vertices_on_tetrahedron[l]:
            result[j].extend(data_on_tetrahedron[l])

答案 3 :(得分:0)

这是我的解决方案:

result = {}
for k,v in vorticies_on_tetrahedron:
    result[k] = [data_on_tetrahedron[i] for i in v]

如果你打算多次使用它,你可以将它包装在一个函数中。