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.
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.
There are a few ways of doing this.
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 list
s (and tuple
s) and has all the problems of copying a list.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.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.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 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 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 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?
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:]
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)
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)
from operator import itemgetter
l = 'ABCD'
for i in itemgetter(slice(1,None))(l):
print(i)
# B
# C
# D