I am using set comprehension to calculate prime numbers between 2 to n, n=132 in the code below.
As long as the value of variable n is <= 131, the prime numbers generated are printed in proper ascending order, viz., {2,3,5,7,11,...}.
Whenever n > 131, the printing order is skewed, for example, {2,3,131,5,7,...}.
No matter the value of 'n', values of the variable 'noPrimes' are always printed in correct order.
I am not quite able to figure out why?
Environment: Python: 3.7.2, macOS: Mojave 10.14.4, IDE: WingPro version 7.0.1.2
Code:
from math import sqrt
n = 132
sqrt_n = int (sqrt(n))
noPrimes = {j for i in range (2, (sqrt_n + 1)) for j in range (i*2, n, i)}
primes = {x for x in range (2,n) if x not in noPrimes}
print ("Printing 'noPrimes':")
print (noPrimes)
print ("Printing 'Primes':")
print (primes)
from math import sqrt
n = 132
sqrt_n = int (sqrt(n))
noPrimes = {j for i in range (2, (sqrt_n + 1)) for j in range (i*2, n, i)}
primes = [x for x in range (2,n) if x not in noPrimes]
print ("Printing 'noPrimes':")
print (sorted(noPrimes))
print ("Printing 'Primes':")
print (primes)
In your example, both noPrimes
and primes
are set, and set are unordered, as evident from the docs: https://docs.python.org/3/library/stdtypes.html#set-types-set-frozenset
A set object is an unordered collection of distinct hashable objects.
from math import sqrt
n = 132
sqrt_n = int (sqrt(n))
noPrimes = {j for i in range (2, (sqrt_n + 1)) for j in range (i*2, n, i)}
primes = {x for x in range (2,n) if x not in noPrimes}
print ("Printing 'noPrimes':")
print (noPrimes)
print ("Printing 'Primes':")
print (primes)
print(type(noPrimes))
print(type(primes))
So the output in the original case will be .
Printing 'noPrimes':
{4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28, 30, 32, 33, 34, 35, 36, 38, 39, 40, 42, 44, 45, 46, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 60, 62, 63, 64, 65, 66, 68, 69, 70, 72, 74, 75, 76, 77, 78, 80, 81, 82, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, 98, 99, 100, 102, 104, 105, 106, 108, 110, 111, 112, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 128, 129, 130}
Printing 'Primes':
{2, 3, 131, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127}
<class 'set'>
<class 'set'>
So the answer you are getting is valid, it is just that they are not in an order
If you want order, what you want to do is list-comprehension like so
from math import sqrt
n = 132
sqrt_n = int (sqrt(n))
#noPrimes is a list
noPrimes = [j for i in range (2, (sqrt_n + 1)) for j in range (i*2, n, i)]
#primes is a list
primes = [x for x in range (2,n) if x not in noPrimes]
print ("Printing 'noPrimes':")
print (noPrimes)
print ("Printing 'Primes':")
print (primes)
print(type(noPrimes))
print(type(primes))
The output will then be
Printing 'noPrimes':
[4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99, 102, 105, 108, 111, 114, 117, 120, 123, 126, 129, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96, 102, 108, 114, 120, 126, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 18, 27, 36, 45, 54, 63, 72, 81, 90, 99, 108, 117, 126, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 22, 33, 44, 55, 66, 77, 88, 99, 110, 121]
Printing 'Primes':
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131]
<class 'list'>
<class 'list'>
@101arrowz provided the correct answer in his comment
Sets are unordered. You won't always get serialized output. You should use list comprehension if you want them in order
To extend that answer, one reason that you might see things ordered for a certain amount of time is that some integers are pre-populated before runtime, giving them a deterministic order of ids (-5,256 for me below with 2.7 and 3.6 cPython).
def collapse(items):
ret = []
if not items:
return ret
first = last = items[0]
for i in items[1:]:
if i == last + 1:
last = i
else:
ret.append((first, last))
first = last = i
ret.append((first, last))
return ret
def pretty_collapse(items):
vals = collapse(items)
return ', '.join('%d..%d' % (a, b) if a != b else '%d' % a
for a, b in vals)
int_by_id = list(sorted(range(-50, 300), key=id))
print(pretty_collapse(int_by_id))
gives
-5..256, -48, -49, -50, -32, -47, -36, -37, -42..-41, -43, -33, -34, -35, -44, -45, -46, -38, -39, -40, -24, -25, -26, -27, -28, -29, -30, -31, -23..-6, 257..299
Note other details in Is it better to use "is" or "==" for number comparison in Python?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.