Цикл через список, начинающийся с определенного элемента

Скажем, у меня есть список:

l = [1, 2, 3, 4] 

И я хочу пройти через него. Обычно это делало бы что-то вроде этого,

 1, 2, 3, 4, 1, 2, 3, 4, 1, 2... 

Я хочу, чтобы начать в определенную точку цикла, не обязательно индекс, но, возможно, соответствующий элемент. Скажем, я хотел начать с любого элемента в списке ==4 , тогда выход будет,

 4, 1, 2, 3, 4, 1, 2, 3, 4, 1... 

Как я могу это сделать?

6 Solutions collect form web for “Цикл через список, начинающийся с определенного элемента”

Посмотрите на модуль itertools . Он обеспечивает все необходимые функции.

 from itertools import cycle, islice, dropwhile L = [1, 2, 3, 4] cycled = cycle(L) # cycle thorugh the list 'L' skipped = dropwhile(lambda x: x != 4, cycled) # drop the values until x==4 sliced = islice(skipped, None, 10) # take the first 10 values result = list(sliced) # create a list from iterator print(result) 

Вывод:

 [4, 1, 2, 3, 4, 1, 2, 3, 4, 1] 

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

 k = (k + 1) % len(l) 

Если вы хотите начать с определенного элемента, а не индекса, вы всегда можете найти его как k = l.index(x) где x – желаемый элемент.

 import itertools as it l = [1, 2, 3, 4] list(it.islice(it.dropwhile(lambda x: x != 4, it.cycle(l)), 10)) # returns: [4, 1, 2, 3, 4, 1, 2, 3, 4, 1] 

поэтому итератор, который вы хотите:

 it.dropwhile(lambda x: x != 4, it.cycle(l)) 

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

 def cycle(my_list, start_at=None): start_at = 0 if start_at is None else my_list.index(start_at) while True: yield my_list[start_at] start_at = (start_at + 1) % len(my_list) 

Это вернет (бесконечный) итератор, зацикливающий ваш список. Чтобы получить следующий элемент цикла, вы должны использовать next оператор:

 >>> it1 = cycle([101,102,103,104]) >>> next(it1), next(it1), next(it1), next(it1), next(it1) (101, 102, 103, 104, 101) # and so on ... >>> it1 = cycle([101,102,103,104], start_at=103) >>> next(it1), next(it1), next(it1), next(it1), next(it1) (103, 104, 101, 102, 103) # and so on ... 

Hm, http://docs.python.org/library/itertools.html#itertools.cycle не имеет такого стартового элемента.

Возможно, вы все равно начинаете цикл и бросаете первые элементы, которые вам не нравятся.

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

 # Run this once myList = ['foo', 'bar', 'baz', 'boom'] myItem = 'baz' # Run this repeatedly to cycle through the list if myItem in myList: myItem = myList[myList.index(myItem)-1] print myItem 
Python - лучший язык программирования в мире.