#python #grouping #chunks
#python #группировка #фрагменты
Вопрос:
У меня есть список, и я хочу сгруппировать свой список в кортежи из трех элементов, используя подход скользящего окна.
На основе параметров, установленных в моем цикле, после i
достижения последних двух элементов кортеж из трех становится усеченным, потому что в конце списка больше нет значений.
Что мне нужно, так это использовать начальные значения, как только оно достигнет этой точки. Пожалуйста, просмотрите скриншот, так как он может лучше визуализировать мою проблему.
test = [(1,2), (3,4), (5,6), (7,8)]
for i in range(len(test)):
print(test[i : i 3])
Вывод:
[(1, 2), (3, 4), (5, 6)]
[(3, 4), (5, 6), (7, 8)]
[(5, 6), (7, 8)]
[(7, 8)]
Однако мне нужно, чтобы это делало:
[(1, 2), (3, 4), (5, 6)]
[(3, 4), (5, 6), (7, 8)]
[(5, 6), (7, 8), (1, 2)]
[(7, 8), (1, 2), (2, 3)]
А затем сглаживается, чтобы в конечном итоге выглядеть так:
[((1, 2), (3, 4), (5, 6))
((3, 4), (5, 6), (7, 8))
((5, 6), (7, 8), (1, 2))
((7, 8), (1, 2), (2, 3))]
Скриншот вывода для большей наглядности
Как я могу это сделать?
Ответ №1:
Могут быть способы оптимизировать следующее, но одним из подходов было бы использовать operator.itemgetter()
и создавать для него правильный набор индексов для каждой подгруппы окон.
from operator import itemgetter
from pprint import pprint
test = [(1,2), (3,4), (5,6), (7,8)]
window_size = 3
length = len(test)
result = []
for i in range(len(test)):
indices = (x%length for x in range(i, i window_size))
result.append(itemgetter(*indices)(test))
pprint(result)
Вывод:
[((1, 2), (3, 4), (5, 6)),
((3, 4), (5, 6), (7, 8)),
((5, 6), (7, 8), (1, 2)),
((7, 8), (1, 2), (3, 4))]
Ответ №2:
Принятый ответ просто прекрасен, но я предложу (то, что я считаю) более простой подход:
test = [(1,2), (3,4), (5,6), (7,8)]
win_size = 3
groups = []
for i in range(len(test)):
groups.append((test[i:] test[:i])[:win_size])
print(groups)
Вывод:
[[(1, 2), (3, 4), (5, 6)],
[(3, 4), (5, 6), (7, 8)],
[(5, 6), (7, 8), (1, 2)],
[(7, 8), (1, 2), (3, 4)]]
Каждый раз в цикле мы переставляем test
их так, чтобы они были в нужном порядке, а затем создаем каждую группу, нарезая размер окна.
Хотя я думаю, что это менее читабельно, вы также можете использовать понимание списка:
groups = [(test[i:] test[:i])[:win_size] for i in range(len(test))]
Если группы должны быть кортежами, а не списками, либо определите test
как кортеж изначально, либо используйте tuple(test[i:] test[:i])
по мере необходимости.