Итератор списка списков итераций часть II - PullRequest
0 голосов
/ 20 февраля 2019

Мне нужен ответ на вопрос Итератор списка списка итераций , то есть, мне нужно отменить

def pivot(a):
   return zip(*(zip(*l) for l in a))

def unpivot(a):
   return <INSSERT_CODE_HERE>

original = [
  (list(range(1,10)), list(range(11,20)), list(range(21,30))),
  (list(range(101,110)), list(range(111,120)), list(range(121,130)))
]
to_be_undone = pivot(original)
original = unpivot(to_be_undone)
original ==  [
  ([1, 2, 3, 4, 5, 6, 7, 8, 9], [11, 12, 13, 14, 15, 16, 17, 18, 19], [21, 22, 23, 24, 25, 26, 27, 28, 29]),
  ([101, 102, 103, 104, 105, 106, 107, 108, 109], [111, 112, 113, 114, 115, 116, 117, 118, 119], [121, 122, 123, 124, 125, 126, 127, 128, 129])
]
# shape: 2 x 3 x 10
to_be_undone = [
  ((1, 11, 21), (101, 111, 121)),
  ((2, 12, 22), (102, 112, 122)),
  ((3, 13, 23), (103, 113, 123)),
  ((4, 14, 24), (104, 114, 124)),
  ((5, 15, 25), (105, 115, 125)),
  ((6, 16, 26), (106, 116, 126)),
  ((7, 17, 27), (107, 117, 127)),
  ((8, 18, 28), (108, 118, 128)),
  ((9, 19, 29), (109, 119, 129))
]
# shape: 10 x 2 x 3

Мы заметили, чтоpivot() фактически выполняет круговое смещение вправо формы a.Определение

def unpivot(a):
   return pivot(pivot(a))

будет работать, но, несомненно, есть лучшее решение для выполнения кругового сдвига влево a формы?

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

1 Ответ

0 голосов
/ 20 февраля 2019

Попробуйте:

def unpivot(a):
   return [tuple(map(list, zip(*l))) for l in zip(*a)]

Тест:

original ==  [
  ([1, 2, 3, 4, 5, 6, 7, 8, 9], [11, 12, 13, 14, 15, 16, 17, 18, 19], [21, 22, 23, 24, 25, 26, 27, 28, 29]),
  ([101, 102, 103, 104, 105, 106, 107, 108, 109], [111, 112, 113, 114, 115, 116, 117, 118, 119], [121, 122, 123, 124, 125, 126, 127, 128, 129])
]

to_be_undone = [
  ((1, 11, 21), (101, 111, 121)),
  ((2, 12, 22), (102, 112, 122)),
  ((3, 13, 23), (103, 113, 123)),
  ((4, 14, 24), (104, 114, 124)),
  ((5, 15, 25), (105, 115, 125)),
  ((6, 16, 26), (106, 116, 126)),
  ((7, 17, 27), (107, 117, 127)),
  ((8, 18, 28), (108, 118, 128)),
  ((9, 19, 29), (109, 119, 129))
]

print(unpivot(to_be_undone) == original)

Если тип данных (кортеж или список) не имеет значения, это также будет работать:

def unpivot(a):
   return [list(zip(*l)) for l in zip(*a)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...