Книга: Practical Programming, Fourth Edition
Назад: Nesting Loops in Loops
Дальше: Repetition Based on User Input

Looping Until a Condition Is Reached

The most general kind of repetition is the while loop

for loops are applicable only if you know how many iterations of the loop you need. In some situations, it is not known in advance how many loop iterations to execute. In a game program, for example, you can’t say in advance whether a player is going to want to play again or quit. In these situations, use a while loop. The general form of a while loop is as follows:

 while​ expression:
  body

The while loop expression is sometimes referred to as the loop condition, and it is similar to condition of an if statement. When Python executes a while loop, it evaluates the loop condition. If that expression evaluates to False, that is the end of the execution of the loop. If the expression evaluates to True, on the other hand, Python executes the loop body once and then returns to the top of the loop to reevaluate the condition. If it still evaluates to True, the loop body is executed again. The process is repeated—expression, body, expression, body—until the expression evaluates to False, at which point Python stops executing the loop.

Here’s an example:

 >>>​​ ​​rabbits​​ ​​=​​ ​​3
 >>>​​ ​​while​​ ​​rabbits​​ ​​>​​ ​​0:
 ...​​ ​​print(rabbits)
 ...​​ ​​rabbits​​ ​​=​​ ​​rabbits​​ ​​-​​ ​​1
 ...
 3
 2
 1

Notice that this loop did not print 0. When the number of rabbits reaches zero, the loop expression evaluates to False, so the body isn’t executed. Here’s a flowchart for this code:

While loop

As a more useful example, you can calculate the growth of a bacterial colony using a simple exponential growth model, which is essentially a calculation of compound interest:

 P(t + 1) = P(t) + r * P(t)

In this formula, P(t) is the population size at time t and r is the growth rate. Using this program, let’s see how long it takes the bacteria to double their numbers:

 time = 0
 population = 1000 ​# 1000 bacteria to start with
 growth_rate = 0.21 ​# 21% growth per minute
 while​ population < 2000:
  population += (growth_rate * population)
  time += 1
 print​(round(population))
 
 print​(f​"It took {time} minutes for the bacteria to double."​)
 print​(f​"The final population was {round(population)} bacteria."​)

Because variable time was updated in the body, its value after the loop was the time of the last iteration, which is exactly what you want. Running this program gives you the answer you were looking for:

 1210
 1464
 1772
 2144
 It took 4 minutes for the bacteria to double.
 The final population was 2144 bacteria.

Infinite Loops

The preceding example used population < 2000 as a loop condition so that the loop stopped when the population reached double its initial size or more. What would happen if you stopped only when the population was exactly double its initial size?

 # Use multivalued assignment to set up controls
 time, population, growth_rate = 0, 1000, 0.21
 
 # Don't stop until we're exactly double the original size
 while​ population != 2000:
  population += (growth_rate * population)
  time += 1
 print​(round(population))
 
 print​(​"It took {time} minutes for the bacteria to double."​)

Here is this program’s output:

 1210
 1464
 1772
 2144
 ...​​3,680​​ ​​lines​​ ​​or​​ ​​so​​ ​​later...
 169691604750803288254070495247627271257136732420488389095435931829
 605433283155791760578073888356200199484802741420740263955981085519
 389894937237162662358663415284584196538765369142779491778980173371
 236929976070662404998070092238388913120403923653584563899266223951
 786043857322378918019475147623289096071282688
 Traceback (most recent call last):
  File "<python-input-0>", line 7, in <module>
  print(round(population))
  ~~~~~^^^^^^^^^^^^
 OverflowError: cannot convert float infinity to integer

Whoops—since the population is never exactly two thousand bacteria, the loop theoretically never stops. The first set of dots represents more than three thousand values, each 21 percent larger than the one before. Eventually, these values are too large for the computer to represent, so the population becomes infinite—from Python’s point of view. The built-in rounding function, round, fails to round and reports an OverflowError, implying that the number is too large, as explained in .

A loop like this one is called an infinite loop, because the computer will execute it forever (or until you kill your program, whichever comes first). In IDLE, you kill your program by selecting ShellRestart Shell. Alternatively, from the command-line shell, you can kill it by pressing Ctrl-C. Infinite loops are a common kind of bug; the typical symptoms include printing the same value repeatedly or hanging (doing nothing at all).

Назад: Nesting Loops in Loops
Дальше: Repetition Based on User Input