117

What is the best way to set a start index when iterating a list in Python. For example, I have a list of the days of the week - Sunday, Monday, Tuesday, ... Saturday - but I want to iterate through the list starting at Monday. What is the best practice for doing this?

3
  • 1
    Do you just want to loop until Saturday, or do you want it to wrap around and print Sunday last? Commented May 27, 2011 at 7:09
  • I just wanted to loop until Saturday. I hadn't realized until now that you can use slicing in Python lists. Commented May 27, 2011 at 15:49
  • is there a solution that deals with generators/iterables too and not only lists? Or really large lists? Commented Aug 9, 2017 at 17:03

9 Answers 9

237

You can use slicing:

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

This will start at the third element and iterate to the end.

Sign up to request clarification or add additional context in comments.

7 Comments

Isn't this inefficient for large lists? I believe this slice operation has to copy the list elements that are being referenced into a new list.
Yes this is inefficient for large lists. See gnibblers answer below for a solution that doesn't copy.
how do u do this though if u are looping using a generators/iterables?
The you should use islice, as suggested in John La Rooy's answer.
@CharlieParker For more functions supporting generators/iterables, take a look at toolz, specifically drop.
|
60

islice has the advantage that it doesn't need to copy part of the list

from itertools import islice
for day in islice(days, 1, None):
    ...

Comments

31

Why are people using list slicing (slow because it copies to a new list), importing a library function, or trying to rotate an array for this?

Use a normal for-loop with range(start, stop, step) (where start and step are optional arguments).

For example, looping through an array starting at index 1:

for i in range(1, len(arr)):
    print(arr[i])

1 Comment

This should be the real answer
13

You can always loop using an index counter the conventional C style looping:

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

It is always better to follow the "loop on every element" style because that's the normal thing to do, but if it gets in your way, just remember the conventional style is also supported, always.

1 Comment

This doesn't work for when you want to start at i=arbitrary index selected in another part of code. Also it doesn't work to first take a slice of the range because then the numbers of the indexes don't line up. Yes that can be accounted for but it's super annoying!
11

stdlib will hook you up son!

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'])

Comments

5

If all you want is to print from Monday onwards, you can use list's index method to find the position where "Monday" is in the list, and iterate from there as explained in other posts. Using list.index saves you hard-coding the index for "Monday", which is a potential source of error:

days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
for d in days[days.index('Monday'):] :
   print d

1 Comment

really nice solution!
5

Here's a rotation generator which doesn't need to make a warped copy of the input sequence ... may be useful if the input sequence is much larger than 7 items.

>>> 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']
>>>

2 Comments

Yes - and would be easy to extend to generate an infinite recurring sequence.
can't help thanking @JohnMachin: great work for someone dead these 264 years
0

If you want to "wrap around" and effectively rotate the list to start with Monday (rather than just chop off the items prior to Monday):

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 )

Comments

0

Loop whole list (not just part) starting from a random pos efficiently:

import random
arr = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
cln = len(arr)
start = random.randint(0, cln-1)
i = 0
while i < cln:
    pos = i+start
    print(arr[pos if pos<cln else pos-cln])
    i += 1

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.