That is impossible to do with list comprehensions but it is possible with generator comprehensions.
What is the difference between the two? List comprehensions will iterate over the iterable all at once and return a list back to you according to your operations on items on the iterable. The key here is all at once.
Your example uses list comprehensions and here's what happens: First the list comprehension is evaluated. In your case it will fail, but even if it didn't fail, it would have iterated over everything in the iterable somelist
and would have returned a resulting list back. Then this list is sliced and a new resulting list is returned.
Generator comprehensions and generators in general have different way of working. They are basically code blocks that are suspended until you request more data from them, which is what you really want to do.
In effect, you create a generator as follows:
g = (p for p in (1,2,3,4,5,0,6) if 100/p )
You now have a generator that will generate values for you when you request it to do so, according to the "rule" you gave it.
As soon as you have a generator at hand, there are several ways you could get n
items from it.
You could write a simple for loop as follows:
results = []
for x in range(3): # n = 3 in your case
results.append(next(g))
Of course, that isn't Pythonic. Assuming you want a list back, you can now use a list comprehension:
results = [next(g) for x in range(3)]
This is the "manual" way of doing it. You could also use the islice
function from the itertools
module (Documentation here):
import itertools
results = list(itertools.islice(g, 4))
And there it is. Generators are pretty useful. A code block that executes when requested to and remember its state is truly invaluable.