2015-08-25 4 views
1

Пусть у меня есть два словаря следующим образом:Сложных ссылок со словарями, питон

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 и значениям, взятым из словаря 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, каждое значение представляет собой список из трех элементов.

К сожалению, я получаю vertices_on_tetrahedron и data_on_tetrahedron в этой форме, поэтому я не могу пересмотреть изменяющиеся структуры данных, чтобы этого избежать.

Если кто-то может также рекомендовать некоторые ссылки для чтения по этим проблемам, я был бы очень признателен.

+1

Что делает 'a'? Кажется, что 'result' может быть построен только из' b' и 'c'. – yangjie

+0

Да, вы правы, но у меня нет 'c'. Я начинаю с 'a',' b' и 'values'. – Pukki

+1

Ваш код будет легче читать, если вы использовали значащие имена. Что должна делать «моя функция»? Почему существуют три результата ('result_lst',' result_tmp', 'result') и какова их связь? И так далее ... Пожалуйста, избавь меня от головной боли :) –

ответ

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) 

Out:

{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) 

Out:

{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]} 
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]) 
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]}) 
0

Вот мое решение :

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

И если вы собираетесь использовать это несколько раз, вы можете обернуть его в функцию.

Смежные вопросы