Я пытаюсь обработать партии вектора
скажем, у меня есть этот вектор
v = [10, 20, 30, 40, 70, 80, 90]
Я хочу напечатать каждые три элемента, если он доходит до конца, он возвращается к началу и берет первый элемент и так далее. Например, вывод будет примерно таким
10, 20, 30
40, 70, 80
90, 10, 20 <== начинается сначала
30, 40, 70
80, 90, 10 <== начинается сначала
и так далее...
Я знаю, что могу сделать это, создав функцию и вычислив начальный и конечный индекс с помощью модуля, но я подумал, есть ли способ просто поиграть с синтаксисом, что-то вроде
v[8:10 % 9] #would print v[8], v[0] and v[1]
Я знаю, что вы можете сделать это для одного индекса v[index % len(v)], но возможно ли это сделать для диапазона v[range % len(v)]?






Хотя вычисление индексов возможно, я бы использовал itertools.cycle с группировщиком zip(*[] * x):
from itertools import cycle
v = [10, 20, 30, 40, 70, 80, 90]
n = 10
for index, *group in zip(range(n), *[cycle(v)] * 3):
print(group)
Измените n на то, сколько раз вы хотите зациклить. Вывод:
[10, 20, 30]
[40, 70, 80]
[90, 10, 20]
[30, 40, 70]
[80, 90, 10]
[20, 30, 40]
[70, 80, 90]
[10, 20, 30]
[40, 70, 80]
[90, 10, 20]
У itertools есть ряд инструментов, которые могут вам в этом помочь:
from itertools import cycle, islice
def chunks(iterable, size):
it = iter(iterable)
item = list(islice(it, size))
while item:
yield item
item = list(islice(it, size))
v = [10, 20, 30, 40, 70, 80, 90]
for subset in chunks(cycle(v), 3):
print(subset)
который производит (выдает):
[10, 20, 30]
[40, 70, 80]
[90, 10, 20]
...
Функция chunks взята из здесь.
Если я правильно понимаю вашу проблему, вам нужна циклическая индексация. Я думаю, что есть два пути достижения этого. Как вы упомянули, с помощью явных функций и других ответов были разработаны. Но вы хотите добиться того же с помощью обычного синтаксиса списка (включая нарезку). Это возможно только в том случае, если вы сделаете подкласс из класса базового списка. Ниже приведен пример того, как это сделать:
class circularlist(list):
def map_key(self, key):
length = len(self)
return key%length
def __getitem__(self, key):
if isinstance(key, int):
return super().__getitem__(self.map_key(key))
elif isinstance(key, slice):
step = key.step if key.step else 1
idx = [i for i in \
range(key.start, key.stop, step)]
return [self.__getitem__(i) for i in idx]
else:
print(type(key))
return super().__getitem__(key)
v = [10, 20, 30, 40, 70, 80, 90]
vv = circularlist(v)
print(vv[42])
print(vv[20:30])
Примечание. Я не рекомендую этого и предлагаю другие методы, описанные выше.