0

I am new to Python. I have below code:

>for e in entries:
     print(e)

But how can I ignore the first element in entries?

I want to iterate from index 1 instead of 0, and to iterate till the last element.

Raúl
  • 1,542
  • 4
  • 24
  • 37

6 Answers6

6

There are a few ways of doing this.

  1. for e in entries[1:]:
        print(e)
    
    This method creates a new list containing all the elements of entries except the first one, and then iterates over that. It's the clearest to read, but only works for lists (and tuples) and has all the problems of copying a list.
  2. iterator = iter(entries)
    next(iterator)
    for e in iterator:
        print(e)
    
    This method creates an iterator, discards the first item and then iterates over it. It's probably the fastest way of doing this,* but it's not very easy to read.
  3. for i, e in enumerate(entries):
        if i > 0:  # or, if i:
            print(e)
    
    This method is not very fast at all, but it's easier to read than the second one. It's probably* worse than the first one, unless you really don't want to make a copy of the list for some reason.
  4. import itertools
    ...
    for e in itertools.islice(entries, 1, None):
        print(e)
    
    This is a version of 2 with all the readability benefits of 1. I'd say that this is probably the best method, but you're safest to go with 1 because it's what people will be expecting.

*: speed shouldn't be a concern until you've tested the code using timeit.timeit (from the timeit module)

To test this, I wrote a hackish test suite:

import timeit

for i, setup in enumerate(("import itertools\nentries=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]", "import itertools\nentries=list(range(1000))", """import itertools
def primes():
    l = [2]
    for n in range(3,1000):
        for prime in l:
            if n % prime != 0:
                break
        else:
            yield n
            l.append(n)
entries=primes()""")):
    for j, stmt in enumerate(("""for e in entries[1:]:
    pass""", """iterator = iter(entries)
next(iterator)
for e in iterator:
    pass""", """for i, e in enumerate(entries):
    if i > 0:
        pass""", """for e in itertools.islice(entries, 1, None):
    pass""")):
        try:
            time = timeit.timeit(stmt=stmt, setup=setup)
        except:
            print(i, j, "DOES NOT WORK")
        else:
            print(i, j, time)

This outputted:

0 0 0.7670026040000266
0 1 0.7781598509996002
0 2 1.794472709999809
0 3 0.9263826839996909
1 0 35.545838756000194
1 1 29.032120127000326
1 2 145.82462093200002
1 3 40.03643834500008
2 0 DOES NOT WORK
2 1 DOES NOT WORK
2 2 0.5132426549998854
2 3 0.490669440000147

As with all such things, the results are not what I would have expected. That's why you never optimise before you test it!

For small inputs

For a small input ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) the first method (slice) was fastest. This is because the cost of creating another list was outweighed by the saving of having fewer bytecodes (basically, less code). This was narrowly followed by the second method (next) due to its efficiency, then the third method (enumerate) because it's got an extra nested iterator. Last and certainly least is the fourth method (islice) because it's got an extra nested iterator that performs a non-trivial function (emulating slice).

For large inputs

For a large input (list(range(1000))), next was fastest (because of the optimisation) followed by slice, followed by islice. And then I fell asleep. And then finally enumerate finished. This was probably because the list was longer than 256, so Python had to create new integer objects for enumerate to number them. It's a long story.

For generator inputs

For a generator input (primes()), slice doesn't work. However, my testing code was wrong, which caused next to error when it shouldn't have, so I can't tell you which was fastest. Sorry!

But it's probably for the best, since timeit.timeit runs 1000000 iterations and my prime calculator function thing was so slow that it wouldn't have finished in my lifetime.

All's well that ends well, right?

wizzwizz4
  • 6,140
  • 2
  • 26
  • 62
  • In #3 you can simply check `if i:` – Mad Physicist Jan 25 '19 at 07:25
  • @MadPhysicist I don't think that's considerably faster (fewer bytecodes though, so maybe) but it doesn't generalise well. I'll edit that into the answer, though. – wizzwizz4 Jan 25 '19 at 07:26
  • @MadPhysicist That's what I was thinking, but in my experience other things you wouldn't expect suddenly become more significant for unexpected reasons. – wizzwizz4 Jan 25 '19 at 07:29
  • Sorry, it was late and I thought I as talking about another answer. Please ignore everything I said. :) – Mad Physicist Jan 25 '19 at 14:47
3

For an iterable:

entries = iter(entries)
next(entries)
for e in entries:

Not for all iterables, but for all sequences.

for e in entries[1:]
DirtyBit
  • 16,613
  • 4
  • 34
  • 55
1

There are multiple ways of skipping the first index of entries.

Example 1: Skipping index using range() function.

Essentially we take the length of entries and start with 1 and end with the length. Then we reference each index using i.

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

Example 2: Change the list.

You can change the contents of the list you iterate through.

for e in entries[1:]:
    print(e)
SafeDev
  • 641
  • 4
  • 12
0

You need to understand indexing for this:

You can get a particular element from a list, for example the element on 6 index using:

entries = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
entries[6]
>> 6

There is also slicing, to retrieve elements from a given range, say from index 1 to index 7

entries[1:8] # syntax-> [starting index: ending_index+1]

>> [1, 2, 3, 4, 5, 6, 7]

But you want to return from index 1 till the end, so you can use:

entries[1:]
>> [1, 2, 3, 4, 5, 6, 7, 8, 9]

If there is no number after the colon (:) then all the elements are returned after the starting index

So you should:

for e in entries[1:]:
     print(e)
Mohit Motwani
  • 4,662
  • 3
  • 17
  • 45
0
entries = 'ABCD'

for e in entries[1:]:
     print(e)

B
C
D

René
  • 4,594
  • 5
  • 23
  • 52
0
from operator import itemgetter

l = 'ABCD'

for i in itemgetter(slice(1,None))(l):
    print(i)

# B
# C
# D
Mykola Zotko
  • 15,583
  • 3
  • 71
  • 73