-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\$
  • 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\$ – Chris Jester-Young Jun 20 '14 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\$ – Martin Ender Jun 20 '14 at 13:32
  • 1
    \$\begingroup\$ @m.buettner There, I edited my comment to say that now. Thanks! :-) \$\endgroup\$ – Chris Jester-Young Jun 20 '14 at 13:35
  • 3
    \$\begingroup\$ Here's an idea to make this non-language-specific: "implement a foreach loop that repeats forever" \$\endgroup\$ – Justin Jun 20 '14 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\$ – Martin Ender Jun 20 '14 at 18:36

10 Answers 10

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\$
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\$
  • \$\begingroup\$ Are you sure this won't transform to a long? \$\endgroup\$ – seequ Jun 20 '14 at 13:18
  • \$\begingroup\$ @TheRare, why would it transform to a long? That aside, a simple test shows arithmetic behaving as expected. \$\endgroup\$ – Peter Taylor Jun 20 '14 at 13:23
  • \$\begingroup\$ That is actually pretty interesting. \$\endgroup\$ – seequ Jun 20 '14 at 13:24
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\$
  • \$\begingroup\$ Actually, the next method is the __iter__ method (which is supposed to return the iterable). Both return self (s) \$\endgroup\$ – Justin Jun 22 '14 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\$
  • \$\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 Jun 20 '14 at 16:28
  • \$\begingroup\$ Well, this does explode the memory very quickly, because the memory usage raises exponentially. \$\endgroup\$ – seequ Jun 20 '14 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 Jun 20 '14 at 21:12
  • \$\begingroup\$ It would probably break eventually, when the list reaches sys.maxsize items. \$\endgroup\$ – nyuszika7h Jul 5 '14 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
    \$\begingroup\$ You don't need to use pass - 1 or i will do just as well. \$\endgroup\$ – isaacg Jul 4 '14 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\$
  • \$\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 Jun 20 '14 at 13:13
  • \$\begingroup\$ @TheRare I suppose, but I'd rather use itertools.count in an production environment than something home-brew. \$\endgroup\$ – ɐɔıʇǝɥʇuʎs Jun 20 '14 at 13:15
  • \$\begingroup\$ Absolutely. Just wanted to inform that the implementation is the same. \$\endgroup\$ – seequ Jun 20 '14 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
    \$\begingroup\$ This will run out of memory, just like histocrat's version. \$\endgroup\$ – Martin Ender Jun 21 '14 at 14:31
  • \$\begingroup\$ @m.buettner indeed it will. Hmm. \$\endgroup\$ – jimsug Jun 21 '14 at 14:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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