Python Forum

Full Version: for loop with 2 conditions
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello,

I'm testing to use a for loop that stops by 2 conditions. For example:

l1 = ['hello', 'bye', 'now', 'before', 'after']
count = 3
for word in l1:
	print(word)
But I want to stop not only when l1 is finished, also when count is 0, and I do it:
l1 = ['hello', 'bye', 'now', 'before', 'after']
count = 3
for word in l1:
	count -=1
	print(word)
	if count == 0:
		break
I don't like... I think that Python should provide me with a more elegant way to do it.
Is it possible?

Thanks
If your intention is to go through first three list items you can do it like this:

l1 = ['hello', 'bye', 'now', 'before', 'after']

for word in l1[0:3]:
    print(word)
Hello ODIS,

thank you. It works.

My English level is low and for this, I simplified the problem, but really I don't have a list (l1), I've a buffer that I don't know how many elements it has, and it changes dynamically.

Then, if use [0:count], maybe I will be out of range.

Of what I'm sure, is that wen I access an element,it exists, because buffer fills up faster than I can empty it.

I hope that I have explained myself acceptably.

Thanks a lot.
Can you please put here more of you code for better understanding its functionality?
Ok ODIS, I try it.. ;) Remember my low English level if I'm wrong whith any word...

First of all, thank you.

I've a buffer that reads from a queue (a kafkaConsumer, but it is not relevant). Then I don't know how many items has 'l1'. Now 'l1' has 3 items, 5 seconds later it has 15 items... But there is always at least one element. Once a value is readed, it is deleted from the buffer.

In each iteration, I read the first value and I work with it. Then If I do this, all works:
#Really, I do not know what is in 'buf'
buf = ['hello', 'bye', 'now', 'before', 'after']
count = 3
for element in buf:
    print(element)
But the buffer never will be empty, and then, the for is running forever. For avoid this, I want to define a number of iterations to stop de loop. I want to do that if I'm in the N iteration, stop to read from the buffer.

I get it:
#Really, I do not know what is in 'buf'
buf = ['hello', 'bye', 'now', 'before', 'after']
count = 3
for element in buf:
    count -=1
    print(element)
    if count == 0:
        break
But I think that is not a god solution. Not elegant. I think that Python must provides me other better way.

In simple list loops, I can use 'if' statements to control this. It is 'pretty'. For example:

test = [i for i in range(200) if i < 10]
print (test)
Output:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In this simple example, althoung the 'for' loop ends in 200 iterations, the 'if' statement makes that really the loop ends at 10 iterations. But I can't use a list for my problem, because in each iteration I work a lot with the item that I read in the bucle. I need a structure like:

#Really, I do not know what is in 'buf'
buf = ['hello', 'bye', 'now', 'before', 'after']
count = 3
for element in buf: #if count >0, 'for example'
    print(element)
I hope to I have explained myself good. ;) Thanks
You could write a generator that makes it look nicer.

>>> def top(count, items):
...   items = iter(items)
...   while count > 0:
...     yield next(items)
...     count -= 1
...
>>> buf = ['hello', 'bye', 'now', 'before', 'after']
>>> for element in top(3, buf):
...   print(element)
...
hello
bye
now
On the other hand, something like that is already available in itertools:
>>> import itertools
>>> for element in itertools.islice(buf, 3):
...   print(element)
...
hello
bye
now
Actually the list slicing is not trowing any exception, so you can use it also in situation when you have less items in a list (at least in Python 3):

l1 = ['hello']
 
for word in l1[0:3]:
    print(word)
If you want to iterate through all items that you have in a list at the moment, you can make a slice of the current length like this:

l1 = ['hello', 'bye', 'now', 'before', 'after']

for word in l1[0:len(l1)]:
    print(word)
So the out of range can never happen.
...as long as it's a list. If it's a different sort of iterable, such as a file or stream/buffer, you can't slice it.
You're right. It was presented as a list type, so I went with that :)
Hi,

thank you. I will work with this. When I have it done, I will write it here.

;)