Python: многомерный дикт - PullRequest
       18

Python: многомерный дикт

2 голосов
/ 26 февраля 2012

Я несколько раз запускал приложение с разными входными параметрами для сбора времени выполнения.

Входные параметры: 6: v, n, m, b, p и c.

Концептуально я могу думать о своих результатах как о многомерном массиве, где любое измерение является другим параметром: times[A][B][C][D][E][F] будет содержать время выполнения моделирования с использованием параметров v=A, n=B, m=C, b=D, p=E и c=F.

Я бы хотел иметь возможность исправить некоторые из этих параметров и перебрать другие:

for A:
  for C:
    for F:
      times[A][0][C][0][0][F]

Значения входных параметров невелики, поэтому я должен использовать словари вместо списков.

Я думал о том, чтобы использовать dict of dict of dict of dict для выполнения всего этого, каждого выполнениявремя будет представлено так:

times = { A:{ B:{ C:{ D:{ E:{ F:{time} } } } } } }

, но это решение выглядит не совсем элегантно: построение всей структуры и повторение по ней - это боль.

Есть ли лучший способработать с моими данными?

Ответы [ 2 ]

7 голосов
/ 26 февраля 2012

Во-первых, если вам нужно использовать словарь, почему бы просто не создать один словарь, используя кортежи для его индексации?Во-вторых, используйте itertools.product, чтобы избежать неприятных вложенных циклов:

>>> import itertools
>>> d = {}
>>> for tup in itertools.product(range(5), repeat=2):
...     d[tup] = tup
... 
>>> d
{(1, 3): (1, 3), (3, 0): (3, 0), (2, 1): (2, 1), (0, 3): (0, 3), (4, 0): (4, 0), 
 (1, 2): (1, 2), (3, 3): (3, 3), (4, 4): (4, 4), (2, 2): (2, 2), (4, 1): (4, 1), 
 (1, 1): (1, 1), (3, 2): (3, 2), (0, 0): (0, 0), (0, 4): (0, 4), (1, 4): (1, 4), 
 (2, 3): (2, 3), (4, 2): (4, 2), (1, 0): (1, 0), (0, 1): (0, 1), (3, 1): (3, 1), 
 (2, 4): (2, 4), (2, 0): (2, 0), (4, 3): (4, 3), (3, 4): (3, 4), (0, 2): (0, 2)}

Однако могут быть более эффективные способы создания разреженного массива.scipy предоставляет разреженных матриц , но я считаю, что они только двумерные.

Вот некоторые другие шаблоны использования, которые могут оказаться полезными:

>>> for tup in itertools.product(range(5), repeat=2):
...     if tup[0] == tup[1]:
...         d[tup] = tup
... 
>>> d
{(3, 3): (3, 3), (0, 0): (0, 0), (1, 1): (1, 1), (4, 4): (4, 4), (2, 2): (2, 2)}

>>> for tup in itertools.product(range(5), range(2)):
...     print d.get(tup)
... 
(0, 0)
None
None
(1, 1)
None
None
None
None
None
None

Чтобы быть менее косым, вот как бы вы держали одну переменную константой: просто передайте последовательность из одного элемента в itertools.product:

>>> for tup in itertools.product(range(3), [2], range(3)):
...     print tup
... 
(0, 2, 0)
(0, 2, 1)
(0, 2, 2)
(1, 2, 0)
(1, 2, 1)
(1, 2, 2)
(2, 2, 0)
(2, 2, 1)
(2, 2, 2)
1 голос
/ 26 февраля 2012

Вы можете создать одномерный словарь, используя комбинацию параметров внутри кортежа в качестве ключа, что было бы намного проще:

times[('v', 'n', 'm', 'b', 'p', 'c')] = value
...