Unlicensed-7-PDF211-212_Haltermanpythonbook

advertisement
9.6.
1
2
3
4
#
#
#
#
5
6
7
202
PRIME GENERATION WITH A LIST
Count the number of prime numbers less
than
2 million and time how long it takes
Compares the performance of two different
algorithms.
from
from
time
math
import
import
clock
sqrt
8
9
10
def
11
12
13
count_primes(n):
'''
Generates all the
prime
numbers
from
2
to
n
-
1.
14
n
''' start
15
1
=
is the
clock()
largest potential prime considered.
# Record start time
16
17
count = 0
for val in range(2, n):
result = True
#
Provisionally, n is prime
root = int(sqrt(val) + 1)
#
Try all potential factors from 2 to the square root of
n
trial_factor = 2
while result and trial_factor <= root:
result = (val % trial_factor != 0 )
# Is it a factor?
trial_factor += 1
# Try next candidate
if result:
count += 1
18
19
20
21
22
23
24
25
26
27
28
29
stop = clock()
print("Count =",
30
count,
#
Stop
"Elapsed
the clock
time:", stop
-
start,
"seconds")
31
32
33
34
def
35
36
37
38
39
40
seive(n):
'''
Generates
all
the
prime
numbers
from
2
to
n
-
1.
n - 1
Algorithm
'''
is the largest potential
originally developed by
prime considered.
Eratosthenes.
41
42
43
44
45
46
47
48
start = clock()
#
Record start time
# Each position in the Boolean list indicates
# if the number of that position is not prime:
# false means "prime," and true means "composite."
# Initially all numbers are prime until proven otherwise
nonprimes =
# Global list initialized to all
* [False]
n
False
49
50
count
=
0
51
52
53
54
#
First prime number is 2; 0 and
prime
nonprimes[0] = nonprimes[1] = True
1
are
not
55
#
Start
at
the
first
prime
number,
2.
Draft date: November 13, 2011
©2011 Richard L. Halterman
9.7.
203
SUMMARY
for
i
#
prime
if
56
57
58
59
in
range(2, n):
See if i is
not nonprimes[i]:
count
+= prime,
1
# It is
so eliminate all of
# multiples that cannot be prime
for j in range(2 *i, n, i):
nonprimes[j] = True
Print the elapsed time
60
61
62
63
64
#
stop = clock()
print("Count =",
65
66
count,
"Elapsed
time:",
stop
its
-
start,
"seconds")
67
68
69
def
main():
count_primes(2000000)
seive(2000000)
70
71
72
73
main()
Since printing to the screen takes up the majority of the time, Listing 9.20 (timeprimes.py) counts the
number of primes rather than printing each one. This allows us to better compare the behavior of the two
approaches. The square root version has been optimized slightly more: the floating-point root variable is
not an integer. The less than comparison between two integers is faster than the floating-point equivalent.
The output of Listing 9.20 (timeprimes.py) on one system reveals
Count = 148932 Elapsed time: 56.446094827055276
seconds
Count = 148933 Elapsed time: 0.8864909583615557
seconds
Our previous version requires almost a minute (56 seconds) to count the number of primes less than two
million, while the version based on the Sieve of Eratosthenes takes less than one second. The Sieve version
is over 60 times faster than the optimized square root version.
9.7
Summary
•
A list represents an ordered sequence of objects
•
An element in a list may be accessed via its index using []. The first element is at index 0. If the list
contains n elements, the index of the last element is n 1.
•
A positive list index is an offset from the beginning of the list. A negative list index is an offset back
from an imaginary element one past the end of the list.
•
A list may elements of different types.
•
List literals list their elements in a comma-separated list enclosed within square brackets ([]).
•
The len function returns the length of the list
•
A list index is sometimes called a subscript.
©2011 Richard L. Halterman
Draft date: November 13, 2011
Download