复杂的字典引用,python
Complicated referencing with dictionaries, python
假设我有两个字典如下:
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
的值列表中的一个数字,值是具有该数字的字典vertices_on_tetrahedron
的键列表。
然后,最终结果是一个字典,其键等于字典tets_sharing_vertex
的键,并且根据字典tets_sharing_vertex
中的值列表从字典b
中取出值。
我实现如下(我承认这很丑):
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
,所以我不能重新考虑更改数据结构来避免这种情况。
如果有人也可以推荐一些参考资料来阅读这类问题,我将不胜感激。
首先,从vertices_on_tetrahedron
构造tets_sharing_vertex
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]}
其次,从data_on_tetrahedron
和tets_sharing_vertex
得到result
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]}
我认为这会起作用:
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])
以下应该比您当前的解决方案工作得更快:
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]})
这是我的解决方案:
result = {}
for k,v in vorticies_on_tetrahedron:
result[k] = [data_on_tetrahedron[i] for i in v]
如果你要多次使用它,你可以将它包装在一个函数中。
假设我有两个字典如下:
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
的值列表中的一个数字,值是具有该数字的字典vertices_on_tetrahedron
的键列表。
然后,最终结果是一个字典,其键等于字典tets_sharing_vertex
的键,并且根据字典tets_sharing_vertex
中的值列表从字典b
中取出值。
我实现如下(我承认这很丑):
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
,所以我不能重新考虑更改数据结构来避免这种情况。
如果有人也可以推荐一些参考资料来阅读这类问题,我将不胜感激。
首先,从vertices_on_tetrahedron
tets_sharing_vertex
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]}
其次,从data_on_tetrahedron
和tets_sharing_vertex
result
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]}
我认为这会起作用:
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])
以下应该比您当前的解决方案工作得更快:
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]})
这是我的解决方案:
result = {}
for k,v in vorticies_on_tetrahedron:
result[k] = [data_on_tetrahedron[i] for i in v]
如果你要多次使用它,你可以将它包装在一个函数中。