Початковий індекс для ітерації списку Python


88

Який найкращий спосіб встановити початковий індекс при ітерації списку на Python. Наприклад, у мене є список днів тижня - неділя, понеділок, вівторок, ... субота - але я хочу переглядати список, починаючи з понеділка. Яка найкраща практика для цього?


1
Ви просто хочете петляти до суботи, або ви хочете, щоб вона обернулася і надрукувала неділю минулої?
juanchopanza

Я просто хотів петляти до суботи. До цього часу я не розумів, що ви можете використовувати нарізання в списках Python.
Вінсент Каталано,

чи є рішення, яке стосується також генераторів / ітерацій, а не лише списків? Або справді великі списки?
Чарлі Паркер,

Відповіді:


174

Ви можете використовувати нарізку :

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

Це почнеться з третього елемента і повториться до кінця.


2
Це саме те, що я шукав. Дякую!
Вінсент Каталано,

30
Хіба це не ефективно для великих списків? Я вважаю, що ця операція зрізу повинна скопіювати елементи списку, на які посилаються, у новий список.
UndeadKernel

4
Так, це неефективно для великих списків. Дивіться відповідь gnibblers нижче щодо рішення, яке не копіюється.
Björn Pollex

як ти це робиш, хоча якщо ти цикл використовуєш генератори / ітерабелі?
Чарлі Паркер,

2
Ви повинні використовувати islice, як пропонується у відповіді Джона Ла Роя.
Björn Pollex

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'', 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-loop з 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 )
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.