-1
\$\begingroup\$

for loops are useful in python in many ways, but one of the most common usages associated with a for loop is it's ability to repeat a certain amount of times. Like this:

for times in range(50):
    print "I'm repeating this 50 times..."

The challenge I propose to you is to make a for repeat forever. If you can find a way to do it without using a recursion, kudos to you. You can use any major version of Python. Just specify which one you are using. The goal is to do this in the smallest file size you can get, and a method that won't "break" after a while. Good luck!

\$\endgroup\$
18
  • 9
    \$\begingroup\$ Ewwww, language-specific challenges. (See meta.codegolf.stackexchange.com/a/234/3 for my stance on this.) (This is unrelated to the reason why I closed the question, which is a site rule and not just a personal opinion.) \$\endgroup\$ Commented Jun 20, 2014 at 13:18
  • 2
    \$\begingroup\$ @ChrisJester-Young I personally think it's fair for programming-puzzles, as they usually tend to work around some feature of a specific language. You could have told the OP though, that your closing the question has nothing to do with your not liking language-specific challenges. So, @ Some Guy, the question is closed because you did not indicate who (among several correct solutions) you will pick the winner of the challenge. Votes? Code-length? Something else? \$\endgroup\$ Commented Jun 20, 2014 at 13:32
  • 1
    \$\begingroup\$ @m.buettner There, I edited my comment to say that now. Thanks! :-) \$\endgroup\$ Commented Jun 20, 2014 at 13:35
  • 3
    \$\begingroup\$ Here's an idea to make this non-language-specific: "implement a foreach loop that repeats forever" \$\endgroup\$
    – Justin
    Commented Jun 20, 2014 at 16:00
  • 2
    \$\begingroup\$ @TheRare Changing the accepted answer is absolutely legitimate if a new winner comes along (by the specified criteria). Therefore, the currently accepted answer isn't even the correct one, actually. \$\endgroup\$ Commented Jun 20, 2014 at 18:36

10 Answers 10

11
\$\begingroup\$

This can be done quite easily by abusing floating point addition.

def frange(start, stop, step):
    r = start
    while r < stop:
        yield r
        r += step

for x in frange(0, 1e16, 1):
    print (x)

IEEE754 64-bit floats have 53 bits of mantissa (including the implicit bit), so if x > 1<<53 then x + 1 == x. 1 << 53 is approximately 9e15.

\$\endgroup\$
3
  • \$\begingroup\$ Are you sure this won't transform to a long? \$\endgroup\$
    – seequ
    Commented Jun 20, 2014 at 13:18
  • \$\begingroup\$ @TheRare, why would it transform to a long? That aside, a simple test shows arithmetic behaving as expected. \$\endgroup\$ Commented Jun 20, 2014 at 13:23
  • \$\begingroup\$ That is actually pretty interesting. \$\endgroup\$
    – seequ
    Commented Jun 20, 2014 at 13:24
7
\$\begingroup\$

Because this was turned to a codegolf, have a 48 bytes version as a one-liner. 3 bytes could be removed from both by replacing print i with pass.

for i in __import__('itertools').count():print i

Or a 47 bytes version with two lines.

from itertools import*
for i in count():print i

Old message:

Easy it is.

def f(i = 0):
    while True:
        yield i
        i += 1
for i in f():
    print(i)
\$\endgroup\$
6
\$\begingroup\$

This is an interesting way of doing it (32 chars for class x, 46 not counting the print):

class x:__iter__=next=lambda s:s
for i in x():print "Hello"

This defines an iterable whose next method never raises a StopIteration

\$\endgroup\$
1
  • \$\begingroup\$ Actually, the next method is the __iter__ method (which is supposed to return the iterable). Both return self (s) \$\endgroup\$
    – Justin
    Commented Jun 22, 2014 at 5:13
3
\$\begingroup\$

I don't usually golf in Python, probably some reason people haven't already done posted this 23-character solution.

x=[1]
for i in x:
 x+=x

Much less memory-hungry if you do x+=[i] instead. Either one hangs my 2.7.5

\$\endgroup\$
4
  • \$\begingroup\$ "and a method that won't "break" after a while." So that's why no one has done this. Or maybe it's because no one was smart enough to think of it. \$\endgroup\$
    – Justin
    Commented Jun 20, 2014 at 16:28
  • \$\begingroup\$ Well, this does explode the memory very quickly, because the memory usage raises exponentially. \$\endgroup\$
    – seequ
    Commented Jun 20, 2014 at 18:56
  • \$\begingroup\$ Yeah, the +=[i] version seems almost legitimate though, I don't know if that would break within any reasonable amount of time. Either way, not as interesting a solution as the others. \$\endgroup\$
    – histocrat
    Commented Jun 20, 2014 at 21:12
  • \$\begingroup\$ It would probably break eventually, when the list reaches sys.maxsize items. \$\endgroup\$
    – user344
    Commented Jul 5, 2014 at 12:11
3
\$\begingroup\$
for i in iter(lambda : 0, 1): 
    print (i) # prints 0 forever 

The iter function is normally used to create an iterator from an iterable.

The iter function can also take two arguments, a callable and a sentinel value. In that case it returns an iterator that yields the result of the callable until the callable returns the sentinel value.

In this case, the callable is a lambda that always returns 0. Since it never can return the sentinel value (1), this will loop forever.

Since this is code golf, this version is 28 characters and only one line:

for i in iter(lambda:0,1):i
\$\endgroup\$
2
\$\begingroup\$

28 bytes, infinite, and no itertools

for x in iter(int,1):print 1

Shouldn't end without system program cutoffs (i.e. not my fault).

22 bytes without printing anything:

for x in iter(int,1):1
\$\endgroup\$
1
\$\begingroup\$

39 Characters, no itertools and no crashing

def f():
 while 1:yield
for i in f():1

Itertools is unnecessary, you can define your own generator.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You don't need to use pass - 1 or i will do just as well. \$\endgroup\$
    – isaacg
    Commented Jul 4, 2014 at 22:16
1
\$\begingroup\$

Python 2 & 3: 37 characters

class P:__getitem__=id
for t in P():1

¡No infinite memory required!

\$\endgroup\$
1
\$\begingroup\$

Itertools, to the rescue:

from itertools import count
for i in count():
    print i

or

from itertools import repeat
for i in repeat(42):
    print i
\$\endgroup\$
3
  • \$\begingroup\$ Just an fyi, itertools.count is the same as my answer and itertools.repeat is almost the same as my original answer. \$\endgroup\$
    – seequ
    Commented Jun 20, 2014 at 13:13
  • \$\begingroup\$ @TheRare I suppose, but I'd rather use itertools.count in an production environment than something home-brew. \$\endgroup\$ Commented Jun 20, 2014 at 13:15
  • \$\begingroup\$ Absolutely. Just wanted to inform that the implementation is the same. \$\endgroup\$
    – seequ
    Commented Jun 20, 2014 at 13:16
0
\$\begingroup\$

Python 3.3: 2 lines, 29 characters

j=[1]  
for i in j: j.append(1)

Does this break? I've run it for a short while, doesn't seem to hang.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ This will run out of memory, just like histocrat's version. \$\endgroup\$ Commented Jun 21, 2014 at 14:31
  • \$\begingroup\$ @m.buettner indeed it will. Hmm. \$\endgroup\$
    – jimsug
    Commented Jun 21, 2014 at 14:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.