यह एराटोस्टेनेस की चाकू नहीं है, भले ही ऐसा लगता है। यह वास्तव में बहुत खराब है। छल खोजने के लिए चलनी सबसे अच्छा एल्गोरिदम है।
देखें http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
संपादित: मैं https://stackoverflow.com/a/9302299/711085 संशोधित कर लिया है एक एक लाइनर होने के लिए (मूल रूप से यह असली चलनी नहीं था, लेकिन अब यह है ... शायद ...):
reduce((lambda r,x: r-set(range(x**2,N,x)) if (x in r) else r),
range(2,N), set(range(2,N)))
डेमो:
>>> primesUpTo(N): lambda N: reduce(...)
>>> primesUpTo(30)
{2, 3, 5, 7, 11, 13, 17, 19}
अफसोस की बात है कि मुझे लगता है कि यह एक कार्यात्मक प्रोग्रामिंग भाषा में कुशल होगा, यह गैर-निरंतर (साझा राज्य और अपरिवर्तनीय) डेटा संरचनाओं के कारण अजगर में उतना ही कुशल नहीं हो सकता है, और अजगर में किसी भी चलनी को उत्परिवर्तन का उपयोग करने की आवश्यकता होगी तुलनीय प्रदर्शन प्राप्त करें। अगर हम बेहद ज़रूरी चाहते हैं तो हम इसे एक लाइनर में भी क्रैम कर सकते हैं। लेकिन पहले...
सामान्य चलनी:
>>> N = 100
>>> table = list(range(N))
>>> for i in range(2,int(N**0.5)+1):
... if table[i]:
... for mult in range(i**2,N,i):
... table[mult] = False
...
>>> primes = [p for p in table if p][1:]
>>> 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]
अब हम को परिभाषित करने और एक ही लाइन पर गुमनाम काम करता है, और साथ ही [...].__setitem__
के हैक फोन इनलाइन उत्परिवर्तन करने के लिए कर सकते हैं और ...
मूल्यांकन करने के लिए ... and foo
के हैक जबकि foo
लौटने :
>>> primesUpTo = lambda N: (lambda table: [[table.__setitem__(mult,False) for mult in range(i**2,N,i)] for i in range(2,int(N**0.5)+1) if table[i]] and [p for p in table if p][1:])(list(range(N)))
>>> primesUpTo(30)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
हॉरर में चापलूसी के लिए आगे बढ़ें, एक लाइनर का विस्तार (विचित्र रूप से सुंदर है क्योंकि आप लगभग सीधे नियंत्रण प्रवाह उसका अनुवाद कर सकें, फिर भी की एक भयानक दुरुपयोग सब कुछ):
lambda N:
(lambda table:
[[table.__setitem__(mult,False) for mult in range(i**2,N,i)]
for i in range(2,int(N**0.5)+1) if table[i]]
and [p for p in table if p][1:]
)(list(range(N)))
यह एक लाइनर परिवर्तनशील संस्करण मेरी मशीन पर लगभग 10 पर छोड़ दिया, जबकि मूल परिवर्तनशील संस्करण लगभग 10 पर छोड़ दिया, स्मृति (विचित्र रूप से) से बाहर चल रहा है।
मूल reduce
संस्करण 10 पर छोड़ दिया गया। तो शायद यह नहीं है कि सभी के बाद अक्षम (कम से कम उन संख्याओं के लिए जिन्हें आप अपने कंप्यूटर पर सौदा कर सकते हैं)।
EDIT2 ऐसा लगता है आप दुष्प्रभाव का दुरुपयोग कर सकते हैं के रूप में अधिक संक्षेप में:
reduce((lambda r,x: (r.difference_update(range(x**2,N,x)) or r)
if (x in r) else r),
range(2,N), set(range(2,N)))
यह लगभग 10 पर देता है, एक लाइनर परिवर्तनशील संस्करण के समान।
edit3: यह runs at हे (एन) empirical complexity, जबकि difference_update
बिना यह O(n^2.2) complexity पर भाग गया।
रेंज उस पर कम हो जाता है ऊपरी सीमा के sqrt के लिए, सीमित है, और काम कर with odds only, अतिरिक्त गति-अप (2x और 1.6x तदनुसार) में दोनों परिणाम:
reduce((lambda r,x: (r.difference_update(range(x*x,N,2*x)) or r)
if (x in r) else r),
range(3, int((N+1)**0.5+1), 2),
set([2] + range(3,N,2)))
आप एक गैर oneliner साथ रह सकते हैं, वहाँ इस सवाल यह है: http://stackoverflow.com/questions/567222/simple- प्राइम जेनरेटर-इन-पायथन – Andy
[पाइथन-इरेटोस्टेनेस-कॉम्पैक्ट पायथन] की संभावित डुप्लिकेट (http://stackoverflow.com/questions/6687296/python-sieve-of-eratosthenes-compact-python) – ninjagecko
मैं सक्षम था इसे दो पंक्तियों में करने के लिए: http://stackoverflow.com/a/9302299/5987 –