212
votes

In python, How do I do something like:

for car in cars:
   # Skip first and last, do work for rest
13
i'm a newbie, but i have been using for n, i in enumerate(cars): if n!= 0: do something to i. the logic is that it adds a 'counter' to each value which you can then target eg with if n == some_value. in this example it would do something to each instance of i, except for the first one. - user1063287

13 Answers

418
votes

To skip the first element in Python you can simply write

for car in cars[1:]:
    # Do What Ever you want

or to skip the last elem

for car in cars[:-1]:
    # Do What Ever you want

You can use this concept for any sequence.

298
votes

The other answers only work for a sequence.

For any iterable, to skip the first item:

itercars = iter(cars)
next(itercars)
for car in itercars:
    # do work

If you want to skip the last, you could do:

itercars = iter(cars)
# add 'next(itercars)' here if you also want to skip the first
prev = next(itercars)
for car in itercars:
    # do work on 'prev' not 'car'
    # at end of loop:
    prev = car
# now you can do whatever you want to do to the last one on 'prev'
34
votes

The best way to skip the first item(s) is:

from itertools import islice
for car in islice(cars, 1, None):
    # do something

islice in this case is invoked with a start-point of 1, and an end point of None, signifying the end of the iterator.

To be able to skip items from the end of an iterable, you need to know its length (always possible for a list, but not necessarily for everything you can iterate on). for example, islice(cars, 1, len(cars)-1) will skip the first and last items in the cars list.

28
votes

Here is a more general generator function that skips any number of items from the beginning and end of an iterable:

def skip(iterable, at_start=0, at_end=0):
    it = iter(iterable)
    for x in itertools.islice(it, at_start):
        pass
    queue = collections.deque(itertools.islice(it, at_end))
    for x in it:
        queue.append(x)
        yield queue.popleft()

Example usage:

>>> list(skip(range(10), at_start=2, at_end=2))
[2, 3, 4, 5, 6, 7]
8
votes
for item in do_not_use_list_as_a_name[1:-1]:
    #...do whatever
6
votes

Example:

mylist=['one','two','three','four','five']
for i in mylist[1:]:
   print(i)

In python index start from 0, We can use slicing operator to make manipulations in iteration.

for i in range(1,-1):
4
votes

Here's my preferred choice. It doesn't require adding on much to the loop, and uses nothing but built in tools.

Go from:

for item in my_items:
  do_something(item)

to:

for i, item in enumerate(my_items):
  if i == 0:
    continue
  do_something(item)
3
votes

Well, your syntax isn't really Python to begin with.

Iterations in Python are over he contents of containers (well, technically it's over iterators), with a syntax for item in container. In this case, the container is the cars list, but you want to skip the first and last elements, so that means cars[1:-1] (python lists are zero-based, negative numbers count from the end, and : is slicing syntax.

So you want

for c in cars[1:-1]:
    do something with c
2
votes

Based on @SvenMarnach 's Answer, but bit simpler and without using deque

>>> def skip(iterable, at_start=0, at_end=0):
    it = iter(iterable)
    it = itertools.islice(it, at_start, None)
    it, it1 = itertools.tee(it)
    it1 = itertools.islice(it1, at_end, None)
    return (next(it) for _ in it1)

>>> list(skip(range(10), at_start=2, at_end=2))
[2, 3, 4, 5, 6, 7]
>>> list(skip(range(10), at_start=2, at_end=5))
[2, 3, 4]

Also Note, based on my timeit result, this is marginally faster than the deque solution

>>> iterable=xrange(1000)
>>> stmt1="""
def skip(iterable, at_start=0, at_end=0):
    it = iter(iterable)
    it = itertools.islice(it, at_start, None)
    it, it1 = itertools.tee(it)
    it1 = itertools.islice(it1, at_end, None)
    return (next(it) for _ in it1)
list(skip(iterable,2,2))
    """
>>> stmt2="""
def skip(iterable, at_start=0, at_end=0):
    it = iter(iterable)
    for x in itertools.islice(it, at_start):
        pass
    queue = collections.deque(itertools.islice(it, at_end))
    for x in it:
        queue.append(x)
        yield queue.popleft()
list(skip(iterable,2,2))
        """
>>> timeit.timeit(stmt = stmt1, setup='from __main__ import iterable, skip, itertools', number = 10000)
2.0313770640908047
>>> timeit.timeit(stmt = stmt2, setup='from __main__ import iterable, skip, itertools, collections', number = 10000)
2.9903135454296716
1
votes

If cars is a sequence you can just do

for car in cars[1:-1]:
    pass
1
votes

An alternative method:

for idx, car in enumerate(cars):
    # Skip first line.
    if not idx:
        continue
    # Skip last line.
    if idx + 1 == len(cars):
        continue
    # Real code here.
    print car
1
votes

The more_itertools project extends itertools.islice to handle negative indices.

Example

import more_itertools as mit

iterable = 'ABCDEFGH'
list(mit.islice_extended(iterable, 1, -1))
# Out: ['B', 'C', 'D', 'E', 'F', 'G']

Therefore, you can elegantly apply it slice elements between the first and last items of an iterable:

for car in mit.islice_extended(cars, 1, -1):
    # do something
-1
votes

I do it like this, even though it looks like a hack it works every time:

ls_of_things = ['apple', 'car', 'truck', 'bike', 'banana']
first = 0
last = len(ls_of_things)
for items in ls_of_things:
    if first == 0
        first = first + 1
        pass
    elif first == last - 1:
        break
    else:
        do_stuff
        first = first + 1
        pass