Циклическая итерация по списку: начиная с элемента X в первом цикле, просматривая полный список после

#python-3.x

#python-3.x

Вопрос:

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

 my_list = [item_1, item_2, item_3]
  

У каждого элемента есть атрибут .attribute .

У меня есть цикл, в котором элементы из моего списка повторяются и используются для вызова функции вместе с атрибутом, вот так:

 while True:

    for i in range(3):
        my_function(my_list[i].attribute)
  

Моя проблема: я хочу иметь возможность выбирать, с какого item пункта my_list начинается итерация, но по мере продолжения цикла я хочу, чтобы следующие итерации начинались с начала my_list . Другими словами, я бы хотел, чтобы цикл проходил следующим образом:

item_2 -> item_3 -> item_1 -> item_2 -> item_3 -> item_1 ....

или:

item_3 -> item_1 -> item_2 -> item_3 -> item_1 ...

В отличие от стандартного поведения:

item_1 -> item_2 -> item_3 -> item_1 ...

Я в недоумении относительно того, как это сделать, и был бы признателен за некоторые указания. Спасибо.

Ответ №1:

Используя cycle и islice из itertools

 for i in itertools.islice(itertools.cycle(my_list), start, stop):
    my_func(i.attribute)
  

Обрабатывать start и stop подобные индексы при нарезке списка repeating_list[start:stop]

Комментарии:

1. разве вы не имели в виду itertools.cycle ?

2. Спасибо. Будет ли это решение работать для диапазона, двух? итак , вместо cycle(my_list могу ли я использовать cycle(range(3)) ?

3. Да, range объекты являются итераторами

4. Из краткого тестирования, которое я только что провел, это, похоже, не делает того, что я хотел. Первая итерация выполняется правильно, но когда она должна повторяться my_list снова, она снова начинается с обозначенного start from itertools.islice . Для цикла с for i in itertools.islice(itertools.cycle(my_list),1,3) тем, что я получаю, это: index 1, index 2, index 1, index 2, index 1, index 2.... в то время как то, что мне нужно, это: index 1, index 2, index 0, index 1, index 2, index 0...

5. Если вы передаете islice 1 и 3 для start и stop , это дает вам только 2 значения. используйте itertools.islice(itertools.cycle(my_list),1,None) , чтобы это продолжалось бесконечно. Вам не нужно, чтобы это было обернуто в цикл while

Ответ №2:

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

 my_function(my_list[3].attribute)
for i in range(3):
    my_function(my_list[i].attribute)
  

Затем вы могли бы использовать условное выражение, чтобы определить, какое item вызывается (или вызывается ли оно вообще) вне цикла for.