Начальный индекс для итерации списка Python

88

Как лучше всего установить начальный индекс при итерации списка в Python. Например, у меня есть список дней недели - воскресенье, понедельник, вторник, ... суббота, - но я хочу перебирать список, начиная с понедельника. Как лучше всего это делать?

Винсент Каталано
источник
1
Вы просто хотите выполнить цикл до субботы или хотите, чтобы он завершился и напечатал последнее воскресенье?
juanchopanza
Я просто хотел зацикливаться до субботы. До сих пор я не осознавал, что вы можете использовать нарезку в списках Python.
Винсент Каталано
есть ли решение, которое также касается генераторов / итераций, а не только списков? Или действительно большие списки?
Чарли Паркер

Ответы:

174

Вы можете использовать нарезку :

for item in some_list[2:]:
    # do stuff

Это начнется с третьего элемента и будет повторяться до конца.

Бьорн Поллекс
источник
2
Это именно то, что я искал. Благодарность!
Винсент Каталано
30
Разве это не неэффективно для больших списков? Я считаю, что эта операция среза должна скопировать элементы списка, на которые ссылаются, в новый список.
UndeadKernel
4
Да, это неэффективно для больших списков. См. Ответ гниблеров ниже, чтобы узнать о решении, которое не копирует.
Björn Pollex
как вы это делаете, если вы зацикливаете с помощью генераторов / итераций?
Чарли Паркер
2
Вы должны использовать islice, как это было предложено в ответе Джона Ла Роя.
Бьёрн Поллекс 09
50

islice имеет то преимущество, что не нужно копировать часть списка

from itertools import islice
for day in islice(days, 1, None):
    ...
Джон Ла Рой
источник
13

Вы всегда можете использовать цикл, используя счетчик индекса, в обычном цикле в стиле C:

for i in range(len(l)-1):
    print l[i+1]

Всегда лучше следовать стилю «цикл на каждом элементе», потому что это нормальное явление, но если это мешает вам, просто помните, что традиционный стиль также поддерживается всегда.

Лакшман Прасад
источник
9

stdlib подключит тебя, сын!

deque.rotate():

#!/usr/local/bin/python2.7

from collections import deque

a = deque('Monday Tuesday Wednesday Thursday Friday Saturday Sunday'.split(' '))
a.rotate(3)
deque(['Friday', 'Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday'])
синтезатор
источник
4

Если все , что вы хотите, чтобы напечатать от Mondayгода, вы можете использовать list«s indexметод , чтобы найти место , где„понедельник“находится в списке, и итерация оттуда , как объяснено в других постах. Использование list.indexизбавляет вас от жесткого кодирования индекса для «понедельника», что может быть потенциальным источником ошибок:

days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
for d in days[days.index('Monday'):] :
   print d
чуанчопанза
источник
действительно хорошее решение!
aderchox
3

Вот генератор вращения, которому не нужно делать деформированную копию входной последовательности ... может быть полезен, если входная последовательность намного больше 7 элементов.

>>> def rotated_sequence(seq, start_index):
...     n = len(seq)
...     for i in xrange(n):
...         yield seq[(i + start_index) % n]
...
>>> s = 'su m tu w th f sa'.split()
>>> list(rotated_sequence(s, s.index('m')))
['m', 'tu', 'w', 'th', 'f', 'sa', 'su']
>>>
Джон Мачин
источник
Да - и его можно было бы легко расширить, чтобы сгенерировать бесконечную повторяющуюся последовательность.
Ленивец
не могу не поблагодарить @JohnMachin: отличная работа для кого-то, кто умер за эти 264 года
jjon
1

Почему люди используют нарезку списка (медленно, потому что копируется в новый список), импортируют библиотечную функцию или пытаются для этого повернуть массив?

Используйте обычный цикл for с range(start, stop, step)(где startи step- необязательные аргументы).

Например, цикл по массиву, начиная с индекса 1:

for i in range(1, len(arr)):
    print(arr[i])
Чарли Су
источник
0

Если вы хотите «обернуть» и эффективно повернуть список, чтобы начать с понедельника (а не просто отбрасывать элементы до понедельника):

dayNames = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 
            'Friday', 'Saturday',  ]

startDayName = 'Monday'

startIndex = dayNames.index( startDayName )
print ( startIndex )

rotatedDayNames = dayNames[ startIndex: ] + dayNames [ :startIndex ]

for x in rotatedDayNames:
    print ( x )
ленивец
источник