Reputation: 31
If I have code like this:
for i in range(3):
print("Hello")
Is there a way to make it print forever with a for
loop?
Upvotes: 1
Views: 2228
Reputation: 31319
If your for loop takes its data from a generator that runs forever, sure:
def infinite():
while True:
yield
for __ in infinite():
print("Hello")
You asked if it could be done as a one-liner. Not like this, but with some trickery (and without cheating by just importing it from elsewhere like itertools
):
for __ in iter(int, 1):
print("Hello")
This works because int()
will just return 0
endlessly, never reaching the sentinel value of 1
. I still feel it's cheating a bit though, you'd only ever do this to make the point that it can be done with for
- obviously while True:
is the way to go if you seriously need this.
You asked how for __ in iter(int, 1):
works exactly. The documentation for iter()
is fairly clear https://docs.python.org/3/library/functions.html#iter, but the short version is that if two arguments are given, the second acts as a sentinel and the first argument has to be a callable which will be called with no arguments and until the sentinel value is returned, all values up to the sentinel will be yielded from the iterator.
For example:
from random import random
def coin_flip():
return 'heads' if random() > .5 else 'tails'
print(list(iter(coin_flip, 'heads')))
Here, coin_flip()
is a function that returns 'heads'
or 'tails'
at random, with an about 50/50 chance. iter(coin_flip, 'heads')
creates an iteratable that will call coin_flip()
and yield the result until it returns the sentinel value (which won't be yielded).
So, there's a 50% chance you get []
, a 25% chance you get ['tails']
, a 12.5% chance you get ['tails', 'tails']
, etc.
Another way to look at it, is a mock implementation of iter()
:
def iter(callable, sentinel):
while (result := callable()) != sentinel:
yield result
This doesn't implement all of iter()
s functionality though, since it works differently if you only call it with a single argument.
In the original answer, it works because int()
will always return 0
, which never becomes 1
, so the iterator yields 0
forever.
Upvotes: 6
Reputation: 5184
Is there any reason it needs to be a for loop?
You could just use a while loop,
while True:
print('hello')
To stop it press Ctrl + c on your keyboard.
Upvotes: 4
Reputation: 114290
You can use something like itertools.count
:
from itertools import count
for i in count():
print(i)
Upvotes: 4