假设我有两个字典如下:
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_tmp
和result
再做一步的原因。
此实现有效,但速度很慢,我实际上需要它来处理大型词典vertices_on_tetrahedron
和data_on_tetrahedron
。 vertices_on_tetrahedron
的结构始终相同:每个键的值列表不超过4个项目。但可能有成千上万的钥匙。对于vertices_on_tetrahedron
,每个值都是一个不超过3个项目的列表。
不幸的是,我收到了vertices_on_tetrahedron
和data_on_tetrahedron
这种形式,因此我无法重新考虑更改数据结构以避免这种情况。
如果有人也可以推荐一些参考来阅读这类问题,我将非常感激。
答案 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]}
其次,从result
和data_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]
如果你打算多次使用它,你可以将它包装在一个函数中。