I’m relatively new to coding and for certain projects I always wonder whether I should use a for loop or a while loop. It seems like the results often don’t differ much. Could someone explain when to use which and what the differences are? Or does it really ‘not matter’?
loops - When to use "while" or "for" in Python - Stack Overflow
What are the differences between a while loop and a for loop? - Software Engineering Stack Exchange
For vs While Loops
performance - Which loop is faster, while or for? - Stack Overflow
Yes, there is a huge difference between while and for.
The for statement iterates through a collection or iterable object or generator function.
The while statement simply loops until a condition is False.
It isn't preference. It's a question of what your data structures are.
Often, we represent the values we want to process as a range (an actual list), or xrange (which generates the values) (Edit: In Python 3, range is now a generator and behaves like the old xrange function. xrange has been removed from Python 3). This gives us a data structure tailor-made for the for statement.
Generally, however, we have a ready-made collection: a set, tuple, list, map or even a string is already an iterable collection, so we simply use a for loop.
In a few cases, we might want some functional-programming processing done for us, in which case we can apply that transformation as part of iteration. The sorted and enumerate functions apply a transformation on an iterable that fits naturally with the for statement.
If you don't have a tidy data structure to iterate through, or you don't have a generator function that drives your processing, you must use while.
while is useful in scenarios where the break condition doesn't logically depend on any kind of sequence. For example, consider unpredictable interactions:
while user_is_sleeping():
wait()
Of course, you could write an appropriate iterator to encapsulate that action and make it accessible via for – but how would that serve readability?¹
In all other cases in Python, use for (or an appropriate higher-order function which encapsulate the loop).
¹ assuming the user_is_sleeping function returns False when false, the example code could be rewritten as the following for loop:
for _ in iter(user_is_sleeping, False):
wait()
The while loop is usually used when you need to repeat something until a given condition is true:
inputInvalid = true;
while(inputInvalid)
{
//ask user for input
invalidInput = checkValidInput();
}
On the other hand, the for loop is usually used when you need to iterate a given number of times:
for(var i = 0; i < 100; i++)
{
...//do something for a 100 times.
}
You can use them interchangeably if you like:
inputInvalid = true;
for(;;)
{
if(!inputInvalid)
{
break;
}
//ask user for input
invalidInput = checkValidInput();
}
Or
inputInvalid = true;
for(;inputInvalid;)
{
//ask user for input
invalidInput = checkValidInput();
}
And:
var i = 0;
while(i < 100)
{
//do your logic here
i++;
}
There is a fundamental difference between the two: with a for loop, you need to know beforehand how often the loop body will be executed. This is a major restriction, since there are many problems where you simply don't know that. Sometimes you don't even know whether or not that number is finite at all!
Consider, for example, a program asking the user to input a series of names. Say, a patient management system for a dentist. How would you know beforehand how many patients the dentist is going to enter? You don't! You can't write a for loop for that.
That clearly depends on the particular implementation of the interpreter/compiler of the specific language.
That said, theoretically, any sane implementation is likely to be able to implement one in terms of the other if it was faster so the difference should be negligible at most.
Of course, I assumed while and for behave as they do in C and similar languages. You could create a language with completely different semantics for while and for
In C#, the For loop is slightly faster.
For loop average about 2.95 to 3.02 ms.
The While loop averaged about 3.05 to 3.37 ms.
Quick little console app to prove:
class Program
{
static void Main(string[] args)
{
int max = 1000000000;
Stopwatch stopWatch = new Stopwatch();
if (args.Length == 1 && args[0].ToString() == "While")
{
Console.WriteLine("While Loop: ");
stopWatch.Start();
WhileLoop(max);
stopWatch.Stop();
DisplayElapsedTime(stopWatch.Elapsed);
}
else
{
Console.WriteLine("For Loop: ");
stopWatch.Start();
ForLoop(max);
stopWatch.Stop();
DisplayElapsedTime(stopWatch.Elapsed);
}
}
private static void WhileLoop(int max)
{
int i = 0;
while (i <= max)
{
//Console.WriteLine(i);
i++;
};
}
private static void ForLoop(int max)
{
for (int i = 0; i <= max; i++)
{
//Console.WriteLine(i);
}
}
private static void DisplayElapsedTime(TimeSpan ts)
{
// Format and display the TimeSpan value.
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine(elapsedTime, "RunTime");
}
}
One main difference is while loops are best suited when you do not know ahead of time the number of iterations that you need to do. When you know this before entering the loop you can use for loop.
A for loop is just a special kind of while loop, which happens to deal with incrementing a variable. You can emulate a for loop with a while loop in any language. It's just syntactic sugar (except python where for is actually foreach). So no, there is no specific situation where one is better than the other (although for readability reasons you should prefer a for loop when you're doing simple incremental loops since most people can easily tell what's going on).
For can behave like while:
while(true)
{
}
for(;;)
{
}
And while can behave like for:
int x = 0;
while(x < 10)
{
x++;
}
for(x = 0; x < 10; x++)
{
}
In your case, yes you could re-write it as a for loop like this:
int counter; // need to declare it here so useTheCounter can see it
for(counter = 0; counter < 10 && !some_condition; )
{
//do some task
}
useTheCounter(counter);
In a nutshell: What your teacher probably meant is that the semantics of while is pretty much the same in most languages, while the semantics of for may change considerably (see discussion below). Hence, abstract language independent proof are more reliable with a while, but one should be careful that a proof with a for loop may not match the semantics of the for loop in many languages.
Your question is not precise enough (though that may not be your fault).
The point is that, afaik, there is no official, ISO supported
standard, or otherwise officially accepted reference definition of
for and while loops. The definition depends on the programming
language.
Hence you cannot make any general statement regarding their equivalence before you have defined precisely what each can do. I adress that more precisely, since it is one of the main argument used in other answers (and the discussion will be useful in what follows).
On intertranslatability of for and while loops
Summary: it depends on the programming language, but is always possible a long as you can have one infinite loop and a way to get out of it.
But you can make such a statement for a specific programming language, and the answer will depend on the features fo the language.
That also means that there is no general proof, but only one for each programming language.
One thing that is generally true is that a while loop can generally
mimic a for loop, because the while loop can do the exit condition
testing of the for loop, doing the initialisation of the control
variable with an assignment before entering the loop, and doing the
incrementation at the end of the loop body, so that
for i from 1 by 2 to 10 do { xxx }
becomes
i=1
while i≤11 do { xxx; i←i+2 }
This more or less works for most languages, but it is not as obvious as it seem, and there may be many "details" to worry about.
For example, in many languages, the for loop evaluates it 3
arguments (initial value, increment, and final value) as strict
arguments, evaluated once before entering the loop, while others will
take then as thunk arguments to be reevaluated at each turn, or
possibly as lazy argument to be evaluated only when first needed.
Another point may be that the increment variable may be local to the
for loop, or have to be a local variable of the function where the
loop appears.
Depending on such issues, the translation of a for to a while may
vary widely, though it is usually possible to achieve it.
The same holds for the converse, thranslating a while into a for loop.
Th first problem is that a while loop will always reevaluate the
exit condition at each turn. But some for loops do not provide for a
condition that is reevaluated at each turn, other than comparison of
the control variable with some fixed value computed on loop entry.
Then the translation is not possible unless there is some other mean
to jump out of the loop on some arbitrary conditions.
That is achievable with various devices, usually starting with a conditional statement testing the condition, followed by an a jump out implemented, as available, by a loop exit statement, a return statement (after encapsulating the loop in a function), a goto statement or an exception raising.
In other words, it is again very dependent on languages, and possibly on subtle features of languages.
This say, as answered by @milleniumbug, the intertranslation is easy
in the language C, because a for lopp is essentially a while loop
plus some extra for an incremented control variable.
But this does not necessarily apply to other languages, and most likely not in the same way.
This being said, programming languages are usually supposed to have Turing power with only one of these loops, since all you need for it is one infinite loop. So, as long as you have some way of looping for ever, and possibly deciding to stop, you are pretty sure you can mimic any other construct ... but not necessarily easily.
Regarding proofs
Summary: There is no reason known to me to assert that proofs should be significantly harder with one or the other (unless some weird feature of the language).
There is probably a misunderstanding, or your teacher had his mind on something else.
Formals semantics can be defined for the various kinds of loops defined in programming languages, and then used for proving properties.
It may be, again depending on the language, that conducting formal proofs regarding programs may be more complex in some cases. But that depends on the language.
I cannot imagine a reason why proofs should be significantly harder with one construct more than with the other. The for loop may be more complex since it can offer, as in C, all that is done with a while plus other things. But if you did it with a while, you would have to add the extras in some other form.
I could use the formal general argument of intertranslatability, as long as there is the possibility for a single infinite loop. I will however refrain from doing that, as the constructions involved are nothing you want to deal with in a proof, and it would clearly be an unfair statement, at least in practice.
Following the above discussion, however, we have seen that the difficulties for intertranslatability come from the great variability of the for loop from language to language. Hence the following conclusion which is probably the right answer:
One possibility to understand your teacher's statement is that the semantics of the while loop is pretty much the same in all programming languages, while the syntax and semantics of the for loop can vary significantly from language to language. Hence, it is possible to make general "abstract" proofs with while loops that have language independent semantics to a good extent, while this is not possible for the for loop that has syntax and semantics changing too much from language to language. But this does not apply within a given language, when the semantics of both are precisely defined.
My best suggestion is that you should ask your teacher what he precisely meant, and whether he can give you an example. Misphrasing or misunderstanding is a common event.
In the C language you can rewrite every for loop to an equivalent while loop and vice versa.
while -> for transformation:
Rewrite
while(condition) { instructions; }
to
for(; condition; ) { instructions; }
for -> while transformation:
This is slightly more complicated, especially if you have continue statement in your loop.
Rewrite:
for(init; condition; next) { instructions; }
to:
{
init;
while(condition)
{
instructions;
next_label:
next;
}
}
but replace every continue; statement with goto next_label; statement. If condition is a null instruction, replace it with true.
As you can see, in C language neither is more "provable" (whatever that means) than the other, since even if one of the loop was, you could rewrite it in terms of another loop.
Now, there exist other languages where this while <-> for equivalency doesn't exist. For example, in Pascal, you can assume more about the for loop. This means that you can't express every concept when writing a for loop, but you can prove more about the flow of the code:
for i:=1 to n do
instructions;
Here, the n is saved at the beginning of the loop, so changes to n don't make any influence on iteration count, and you can't modify i in the body of the loop. This means you can trivially prove this loop will eventually end (as n is finite, and you can't modify i).
In your case, you don't gain much besides one less line of code in the for loop.
However, if you declare the loop like so:
for(int i = 0; i < x; i++)
You manage to keep i within the scope of the loop, instead of letting it escape to the rest of the code.
Also, in a while loop, you have the variable declaration, the condition, and the increment in 3 different places. With the for loop, it is all in one convenient, easy-to-read place.
Last thought:
One more important note. There is a semantic difference between the two. While loops, in general, are meant to have an indefinite number of iterations. (ie. until the file has been read..no matter how many lines are in it), and for loops should have a more definite number of iterations. (loop through all of the elements in a collection, which we can count based on the size of the collection.)
There is one reason to choose for over while: Readability.
By using a for loop, you're expressly saying your intent is to perform some type of operating that requires an initialization, a "step" operation, and a completion condition.
With while, on the other hand, you're only saying you need the completion condition.
There is usually not a question. If you need to run a fixed number of loops, or you need to do something once for each item in a collection, then you want a for loop. Anything based on a counter uses a for loop. If you need to loop until some specific condition happens, or loop forever, then you want a while.
# Print 5 numbers.
for i in range(5):
print(i)
It's usually obvious when you've made the wrong choice:
i = 0
while i < 5:
print(i)
i += 1
That's a lot of extra typing to do what the for loop does.
lst = [5,4,3,2,1]
for n in lst:
print("This element is",n)
But here is a case where while is better:
while True:
s = input("Type q to quit: ")
if s == 'q':
break
For ends by itself when it comes to the end of iterable
While ends when its condition is False
if there is some condition you need to check on every loop you need to use While
if there is an iterable object you need to iterate on you've to use for
I think you're drawing the wrong conclusion from the advice you've been given.
The reason (in this instance at least) to prefer the for construct over the while has nothing to do with efficiency; it's all about writing code that expresses your intentions in a clear and easy to understand manner.
The for places the initial condition, increment, and exit condition all in one place, making it easier to understand. The while loop spreads them around. For example, in your sample, what is the initial value of i? -oh, you forgot to specify it? --that's the point.
That depends on the exact compiler that you use. In your example, a good compiler will create the same machine code for both options.