जवाबों:
पायथन में 2.x:
range
एक सूची बनाता है, इसलिए यदि आप ऐसा करते हैं तो तत्वों के range(1, 10000000)
साथ स्मृति में एक सूची बनाता है 9999999
।
xrange
एक अनुक्रम वस्तु है जो आलसी का मूल्यांकन करती है।
पायथन 3 में, range
अजगर के बराबर है xrange
, और सूची प्राप्त करने के लिए, आपको उपयोग करना होगा list(range(...))
।
xrange(x).__iter__()
एक जनरेटर है।
i
का मूल्यांकन आरंभीकरण के बजाय मांग पर किया जाता है।
रेंज एक सूची बनाता है, इसलिए यदि आप ऐसा करते हैं तो तत्वों के
range(1, 10000000)
साथ स्मृति में एक सूची बनाता है9999999
।
xrange
एक जनरेटर है, इसलिए यहएक अनुक्रम वस्तुहै जोकि आलसी का मूल्यांकन करता है।
यह सच है, लेकिन पायथन 3 में, .range()
पायथन 2 द्वारा लागू किया जाएगा .xrange()
। यदि आपको वास्तव में सूची तैयार करने की आवश्यकता है, तो आपको करना होगा:
list(range(1,100))
xrange
जनरेटर कॉल करने में क्या गलत है ? यह एक फ़ंक्शन है जिसमें yield
स्टेटमेंट होता है, और शब्दावली के अनुसार ऐसे कार्यों को जनरेटर कहा जाता है।
याद रखें, timeit
कोड के छोटे स्निपेट में से कौन सा परीक्षण तेज है , इसका उपयोग करें !
$ python -m timeit 'for i in range(1000000):' ' pass'
10 loops, best of 3: 90.5 msec per loop
$ python -m timeit 'for i in xrange(1000000):' ' pass'
10 loops, best of 3: 51.1 msec per loop
व्यक्तिगत रूप से, मैं हमेशा उपयोग करता हूं .range()
, जब तक कि मैं वास्तव में विशाल सूचियों के साथ काम नहीं कर रहा था - जैसा कि आप देख सकते हैं, समय-वार, एक लाख प्रविष्टियों की सूची के लिए, अतिरिक्त ओवरहेड केवल 0.04 सेकंड है। और जैसा कि कोरी बताता है, पायथन 3.0 में .xrange()
दूर चला जाएगा और .range()
आपको वैसे भी अच्छा इटेरेटर व्यवहार देगा।
python -m timeit "for i in xrange(1000000):" " pass"
the extra overhead is only 0.04 seconds
इसे देखने का सही तरीका नहीं है, (90.5-51.1)/51.1 = 1.771 times slower
सही है क्योंकि यह बताता है कि यदि यह आपके प्रोग्राम का मुख्य लूप है तो यह संभावित रूप से इसे अड़चन दे सकता है। हालाँकि, अगर यह एक छोटा हिस्सा है तो 1.77x ज्यादा नहीं है।
xrange
केवल सीमा पारामों को संग्रहीत करता है और मांग पर संख्या उत्पन्न करता है। हालाँकि वर्तमान में पायथन का C कार्यान्वयन सी लॉन्ग के लिए इसके आर्ग को प्रतिबंधित करता है:
xrange(2**32-1, 2**32+1) # When long is 32 bits, OverflowError: Python int too large to convert to C long
range(2**32-1, 2**32+1) # OK --> [4294967295L, 4294967296L]
ध्यान दें कि पायथन 3.0 में केवल है range
और यह 2.x की तरह व्यवहार करता है xrange
लेकिन न्यूनतम और अधिकतम अंत बिंदुओं पर सीमाओं के बिना।
xrange एक पुनरावृत्ति रिटर्न देता है और केवल एक समय में एक नंबर को मेमोरी में रखता है। रेंज मेमोरी में संख्याओं की पूरी सूची रखता है।
xrange
एक पुनरावृत्ति वापस नहीं करता है।
and only keeps one number in memory at a time
और बाकी जगह पर कृपया मेरा मार्गदर्शन करें ..
लाइब्रेरी संदर्भ के साथ कुछ समय बिताएं । जितना अधिक आप इसके साथ परिचित हैं, उतनी ही तेज़ी से आप इस तरह के सवालों के जवाब पा सकते हैं। विशेष रूप से महत्वपूर्ण बिलिन वस्तुओं और प्रकारों के बारे में पहले कुछ अध्याय हैं।
Xrange प्रकार का लाभ यह है कि एक xrange ऑब्जेक्ट हमेशा एक ही मात्रा में मेमोरी लेगा, इससे कोई फर्क नहीं पड़ता कि यह किस रेंज का प्रतिनिधित्व करता है। कोई निरंतर प्रदर्शन लाभ नहीं हैं।
पायथन निर्माण के बारे में त्वरित जानकारी प्राप्त करने का एक और तरीका है डॉकस्ट्रिंग और हेल्प-फंक्शन:
print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)
मैं हैरान हूं कि कोई भी डॉक्टर को नहीं पढ़ता है :
यह फ़ंक्शन बहुत समान है
range()
, लेकिनxrange
किसी सूची के बजाय एक वस्तु देता है । यह एक अपारदर्शी अनुक्रम प्रकार है जो संबंधित सूची के समान मूल्यों को प्राप्त करता है, वास्तव में उन सभी को एक साथ संग्रहीत किए बिना।xrange()
ओवरrange()
का लाभ कम से कम है (क्योंकिxrange()
अभी भी मूल्यों को बनाने के लिए जब उनके लिए कहा जाता है) को छोड़कर जब एक बहुत बड़ी सीमा का उपयोग मेमोरी-स्टैडर्ड मशीन पर किया जाता है या जब रेंज के सभी तत्वों का उपयोग कभी नहीं किया जाता है (जैसे कि जब लूप होता है) आमतौर पर के साथ समाप्तbreak
)।
रेंज एक सूची बनाता है, इसलिए यदि आप रेंज (1, 10000000) करते हैं तो यह 10000000 तत्वों के साथ मेमोरी में एक सूची बनाता है। xrange एक जनरेटर है, इसलिए यह आलसी का मूल्यांकन करता है।
इससे आपको दो फायदे होंगे:
MemoryError
।आपको इस सरल उदाहरण में xrange
ओवर का लाभ मिलेगा range
:
import timeit
t1 = timeit.default_timer()
a = 0
for i in xrange(1, 100000000):
pass
t2 = timeit.default_timer()
print "time taken: ", (t2-t1) # 4.49153590202 seconds
t1 = timeit.default_timer()
a = 0
for i in range(1, 100000000):
pass
t2 = timeit.default_timer()
print "time taken: ", (t2-t1) # 7.04547905922 seconds
उपरोक्त उदाहरण के मामले में कुछ भी बेहतर नहीं दर्शाता है xrange
।
अब निम्नलिखित मामले को देखें, जहां range
की तुलना में वास्तव में धीमा है xrange
।
import timeit
t1 = timeit.default_timer()
a = 0
for i in xrange(1, 100000000):
if i == 10000:
break
t2 = timeit.default_timer()
print "time taken: ", (t2-t1) # 0.000764846801758 seconds
t1 = timeit.default_timer()
a = 0
for i in range(1, 100000000):
if i == 10000:
break
t2 = timeit.default_timer()
print "time taken: ", (t2-t1) # 2.78506207466 seconds
इसके साथ range
, यह पहले से ही 0 से 100000000 (समय लेने वाली) की सूची बनाता है, लेकिन xrange
एक जनरेटर है और यह केवल आवश्यकता के आधार पर संख्या उत्पन्न करता है, अर्थात्, यदि पुनरावृत्ति जारी रहती है।
पायथन -3 में, range
कार्यक्षमता का कार्यान्वयन xrange
पाइथन -2 के समान है, जबकि उन्होंने xrange
पायथन -3 में भाग लिया है
हैप्पी कोडिंग !!
यह अनुकूलन कारणों के लिए है।
रेंज () शुरू से अंत तक मानों की एक सूची बनाएगी (आपके उदाहरण में 0 .. 20)। यह बहुत बड़ी सीमाओं पर एक महंगा ऑपरेशन बन जाएगा।
दूसरी ओर xrange () बहुत अधिक अनुकूलित है। यह केवल अगले मूल्य की गणना करेगा जब जरूरत (एक xrange अनुक्रम ऑब्जेक्ट के माध्यम से) और रेंज () करता है जैसे सभी मूल्यों की सूची नहीं बनाता है।
range(x,y)
x और y के बीच की प्रत्येक संख्या की सूची देता है यदि आप for
लूप का उपयोग करते हैं , तो range
धीमा है। वास्तव में, range
एक बड़ी सूचकांक सीमा है। range(x.y)
x और y के बीच के सभी नंबरों की सूची का प्रिंट आउट लेगा
xrange(x,y)
रिटर्न xrange(x,y)
लेकिन अगर आपने एक for
लूप का उपयोग किया है , तो xrange
तेज है। xrange
एक छोटी सूचकांक सीमा है। xrange
न केवल प्रिंट आउट xrange(x,y)
लेगा, बल्कि यह उन सभी नंबरों को रखेगा जो इसमें हैं।
[In] range(1,10)
[Out] [1, 2, 3, 4, 5, 6, 7, 8, 9]
[In] xrange(1,10)
[Out] xrange(1,10)
यदि आप एक for
लूप का उपयोग करते हैं , तो यह काम करेगा
[In] for i in range(1,10):
print i
[Out] 1
2
3
4
5
6
7
8
9
[In] for i in xrange(1,10):
print i
[Out] 1
2
3
4
5
6
7
8
9
छोरों का उपयोग करते समय बहुत अंतर नहीं होता है, हालांकि सिर्फ इसे प्रिंट करते समय एक अंतर होता है!
रेंज (): रेंज (१, १०) १ से १० संख्याओं की सूची देती है और पूरी सूची को स्मृति में रखती है।
xrange (): रेंज की तरह (), लेकिन एक सूची को वापस करने के बजाय, एक ऐसी वस्तु लौटाता है जो मांग पर रेंज में संख्या उत्पन्न करती है। लूपिंग के लिए, यह रेंज () और अधिक मेमोरी कुशल की तुलना में हल्का तेज़ है। xrange () ऑब्जेक्ट एक पुनरावृत्त की तरह और मांग पर संख्या उत्पन्न करता है। (आलसी मूल्यांकन)
In [1]: range(1,10)
Out[1]: [1, 2, 3, 4, 5, 6, 7, 8, 9]
In [2]: xrange(10)
Out[2]: xrange(10)
In [3]: print xrange.__doc__
xrange([start,] stop[, step]) -> xrange object
अन्य उत्तर में से कुछ है कि अजगर 3 सफाया 2.x के उल्लेख range
और 2.x के नाम दिया xrange
करने के लिए range
। हालाँकि, जब तक आप 3.0 या 3.1 (जो कोई भी नहीं होना चाहिए) का उपयोग कर रहे हैं, यह वास्तव में एक अलग प्रकार है।
के रूप में 3.1 डॉक्स कहते हैं:
रेंज ऑब्जेक्ट में बहुत कम व्यवहार होता है: वे केवल अनुक्रमण, पुनरावृत्ति और
len
फ़ंक्शन का समर्थन करते हैं।
हालाँकि, 3.2+ में, range
एक पूर्ण अनुक्रम है - यह विस्तारित स्लाइस का समर्थन करता है, और सभी विधियों के collections.abc.Sequence
समान शब्दार्थ a के साथ list
। *
और, CPython और PyPy (केवल दो 3.2+ कार्यान्वयन कि वर्तमान में मौजूद) में कम से कम, यह भी की लगातार समय कार्यान्वयन है index
और count
तरीकों और in
ऑपरेटर (जब तक आप केवल पूर्णांकों पारित रूप में)। इसका मतलब है कि लेखन 123456 in r
3.2+ में उचित है, जबकि 2.7 या 3.1 में यह एक भयानक विचार होगा।
* तथ्य यह है कि 2.6-2.7 और 3.0-3.1 में issubclass(xrange, collections.Sequence)
रिटर्न एक बग है जो 3.2 में तय किया गया था और बैकपोर्ट नहीं किया गया था।True
अजगर में 2.x
रेंज (x) एक सूची देता है, जो x तत्वों के साथ मेमोरी में बनाई जाती है।
>>> a = range(5)
>>> a
[0, 1, 2, 3, 4]
xrange (x) एक xrange ऑब्जेक्ट देता है जो एक जनरेटर ओब्ज है जो मांग पर संख्या उत्पन्न करता है। वे लूप (आलसी मूल्यांकन) के लिए गणना की जाती हैं।
लूपिंग के लिए, यह रेंज () और अधिक मेमोरी कुशल की तुलना में थोड़ा तेज है।
>>> b = xrange(5)
>>> b
xrange(5)
xrange()
जेनरेटर नहीं है। xrange(n)
.__ iter __ () `है।
जब लूप में xrange के खिलाफ परीक्षण सीमा होती है (मुझे पता है कि मुझे timeit का उपयोग करना चाहिए , लेकिन यह एक साधारण सूची समझ उदाहरण का उपयोग करके मेमोरी से तेजी से हैक किया गया था) मुझे निम्नलिखित मिला:
import time
for x in range(1, 10):
t = time.time()
[v*10 for v in range(1, 10000)]
print "range: %.4f" % ((time.time()-t)*100)
t = time.time()
[v*10 for v in xrange(1, 10000)]
print "xrange: %.4f" % ((time.time()-t)*100)
जो देता है:
$python range_tests.py
range: 0.4273
xrange: 0.3733
range: 0.3881
xrange: 0.3507
range: 0.3712
xrange: 0.3565
range: 0.4031
xrange: 0.3558
range: 0.3714
xrange: 0.3520
range: 0.3834
xrange: 0.3546
range: 0.3717
xrange: 0.3511
range: 0.3745
xrange: 0.3523
range: 0.3858
xrange: 0.3997 <- garbage collection?
या, लूप के लिए xrange का उपयोग कर:
range: 0.4172
xrange: 0.3701
range: 0.3840
xrange: 0.3547
range: 0.3830
xrange: 0.3862 <- garbage collection?
range: 0.4019
xrange: 0.3532
range: 0.3738
xrange: 0.3726
range: 0.3762
xrange: 0.3533
range: 0.3710
xrange: 0.3509
range: 0.3738
xrange: 0.3512
range: 0.3703
xrange: 0.3509
क्या मेरे स्निपेट का परीक्षण ठीक से हो रहा है? Xrange के धीमे उदाहरण पर कोई टिप्पणी? या एक बेहतर उदाहरण :-)
xrange
थोड़ा तेज लग रहा था, हालांकि पायथन 3 के साथ तुलना अब बेमानी है।
timeit
है जिसके लिए है यह कई बार चल जीसी अक्षम करने के बजाय, सबसे अच्छा घड़ी का उपयोग करने का का ख्याल रखता है time
आदि,
अजगर में xrange () और रेंज () उपयोगकर्ता के लिए समान रूप से काम करता है, लेकिन अंतर तब आता है जब हम बात कर रहे हैं कि दोनों फ़ंक्शन का उपयोग करके मेमोरी कैसे आवंटित की जाती है।
जब हम रेंज () का उपयोग कर रहे हैं तो हम उन सभी वेरिएबल्स के लिए मेमोरी आवंटित करते हैं जो इसे उत्पन्न कर रहे हैं, इसलिए इसे बड़े नहीं के साथ उपयोग करने की अनुशंसा नहीं की जाती है। उत्पन्न होने वाले चर।
दूसरी ओर xrange () एक समय में केवल एक विशेष मूल्य उत्पन्न करता है और केवल लूप के साथ सभी आवश्यक मूल्यों को प्रिंट करने के लिए उपयोग किया जा सकता है।
क्या?
range
रनटाइम पर एक स्थिर सूची देता है।
xrange
रिटर्न object
(जो एक जनरेटर की तरह काम करता है, हालांकि यह निश्चित रूप से एक नहीं है) जहां से आवश्यक होने पर मान उत्पन्न होते हैं।
कब कौन सा उपयोग करें?
xrange
अगर आप एक विशाल श्रृंखला के लिए एक सूची उत्पन्न करना चाहते हैं, 1 अरब का कहना है, खासकर जब आप एक सेल फोन की तरह एक "स्मृति संवेदनशील प्रणाली" है।range
यदि आप कई बार सूची में पुनरावृति करना चाहते हैं तो इसका उपयोग करें ।पुनश्च: पायथन 3.x का range
कार्य == पायथन 2.x का xrange
कार्य।
xrange
जेनरेटर ऑब्जेक्ट वापस नहीं करता है।
सभी ने इसे बहुत समझाया है। लेकिन मैं इसे अपने लिए देखना चाहता था। मैं python3 का उपयोग करता हूं। इसलिए, मैंने संसाधन मॉनिटर (विंडोज में!) खोला, और सबसे पहले, निम्नलिखित कमांड को पहले निष्पादित किया:
a=0
for i in range(1,100000):
a=a+i
और फिर 'इन यूज़' मेमोरी में बदलाव की जाँच की। यह नगण्य था। फिर, मैंने निम्नलिखित कोड चलाया:
for i in list(range(1,100000)):
a=a+i
और यह तुरंत उपयोग के लिए मेमोरी का एक बड़ा हिस्सा ले गया। और, मैं आश्वस्त था। आप इसे अपने लिए आजमा सकते हैं।
यदि आप पायथन 2X का उपयोग कर रहे हैं, तो 'कोड ()' के साथ 'कोड' (') को पहले कोड में और' लिस्ट (रेंज) (')' को 'रेंज ()' से बदलें।
मदद डॉक्स से।
पायथन 2.7.12
>>> print range.__doc__
range(stop) -> list of integers
range(start, stop[, step]) -> list of integers
Return a list containing an arithmetic progression of integers.
range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
When step is given, it specifies the increment (or decrement).
For example, range(4) returns [0, 1, 2, 3]. The end point is omitted!
These are exactly the valid indices for a list of 4 elements.
>>> print xrange.__doc__
xrange(stop) -> xrange object
xrange(start, stop[, step]) -> xrange object
Like range(), but instead of returning a list, returns an object that
generates the numbers in the range on demand. For looping, this is
slightly faster than range() and more memory efficient.
पायथन 3.5.2
>>> print(range.__doc__)
range(stop) -> range object
range(start, stop[, step]) -> range object
Return an object that produces a sequence of integers from start (inclusive)
to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.
start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.
These are exactly the valid indices for a list of 4 elements.
When step is given, it specifies the increment (or decrement).
>>> print(xrange.__doc__)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'xrange' is not defined
अंतर स्पष्ट है। पायथन 2.x में, range
एक सूची लौटाता है, xrange
एक xrange ऑब्जेक्ट देता है जो कि चलने योग्य है।
पायथन 3.x में, पायथन 2.x का range
हो जाता xrange
है, और xrange
हटा दिया जाता है।
0-एन आइटम की स्कैनिंग / प्रिंटिंग के लिए एक आवश्यकता पर, रेंज और xrange इस प्रकार काम करता है।
रेंज () - मेमोरी में एक नई सूची बनाता है और पूरे 0 से N आइटम (पूरी तरह से N + 1) तक ले जाता है और उन्हें प्रिंट करता है। xrange () - आइटम के माध्यम से स्कैन करने वाला एक इटरेटर उदाहरण बनाता है और मेमोरी में केवल वर्तमान सामना किए गए आइटम को रखता है, इसलिए हर समय उसी मात्रा में मेमोरी का उपयोग करता है।
यदि आवश्यक तत्व सूची की शुरुआत में कुछ हद तक है, तो यह समय और स्मृति की एक अच्छी राशि बचाता है।
xrange
एक पुनरावृत्त उदाहरण नहीं बनाता है। यह एक xrange
ऑब्जेक्ट बनाता है , जो चलने-फिरने योग्य है, लेकिन इट्रेटर नहीं है - लगभग (लेकिन बिल्कुल नहीं) एक अनुक्रम, एक सूची की तरह।
रेंज एक सूची लौटाती है जबकि xrange एक xrange ऑब्जेक्ट देता है जो समान आकार के बावजूद एक ही मेमोरी लेता है, क्योंकि इस मामले में, केवल एक तत्व उत्पन्न होता है और प्रति पुनरावृत्ति उपलब्ध है जबकि रेंज का उपयोग करने के मामले में, सभी तत्व एक ही बार में उत्पन्न होते हैं और मेमोरी में उपलब्ध हैं।
अंतर करने के लिए छोटे तर्क के लिए कम हो जाती है range(..)
/ xrange(..)
:
$ python -m timeit "for i in xrange(10111):" " for k in range(100):" " pass"
10 loops, best of 3: 59.4 msec per loop
$ python -m timeit "for i in xrange(10111):" " for k in xrange(100):" " pass"
10 loops, best of 3: 46.9 msec per loop
इस मामले xrange(100)
में केवल 20% अधिक कुशल है।
रेंज: -range एक ही बार में सब कुछ आबाद कर देगा। इसका मतलब है कि रेंज की हर संख्या मेमोरी पर कब्जा कर लेगी।
xrange: -xrange कुछ ऐसा है जैसे जनरेटर, यह तब आएगा जब आप संख्याओं की सीमा चाहते हैं, लेकिन आप नहीं चाहते कि उन्हें संग्रहीत किया जाए, जैसे कि आप लूप के लिए उपयोग करना चाहते हैं। स्मृति कुशल।
इसके अतिरिक्त, अगर करना list(xrange(...))
बराबर होगाrange(...)
।
इसलिए list
धीमा है।
भी xrange
वास्तव में पूरी तरह से अनुक्रम खत्म नहीं करता है
तो इसीलिए इसकी सूची नहीं, यह एक xrange
वस्तु है
range()
अजगर में 2.x
यह फ़ंक्शन अनिवार्य रूप से पुराना range()
फ़ंक्शन है जो पायथन में उपलब्ध था 2.x
और एक list
ऑब्जेक्ट का एक उदाहरण देता है जिसमें निर्दिष्ट सीमा में तत्व होते हैं।
हालाँकि, यह कार्यान्वयन बहुत अक्षम है जब यह संख्या की एक सूची के साथ सूची को आरम्भ करने की बात करता है। उदाहरण के लिए, for i in range(1000000)
निष्पादित करने के लिए एक बहुत महंगी कमांड होगी, दोनों मेमोरी और समय के उपयोग के संदर्भ में क्योंकि इस मेमोरी में इस सूची के भंडारण की आवश्यकता होती है।
range()
पायथन में 3.x
और xrange()
पायथन में2.x
अजगर 3.x
ने एक नया कार्यान्वयन शुरू किया range()
(जबकि नया कार्यान्वयन पहले से ही अजगर के 2.x
माध्यम से उपलब्ध थाxrange()
फ़ंक्शन के )।
range()
एक रणनीति के रूप में जाना कारनामे आलसी मूल्यांकन। श्रेणी में तत्वों की एक विशाल सूची बनाने के बजाय, नया कार्यान्वयन वर्ग का परिचय देता है range
, एक हल्की वस्तु जो किसी दिए गए रेंज में आवश्यक तत्वों का प्रतिनिधित्व करती है, उन्हें स्मृति में स्पष्ट रूप से संग्रहीत किए बिना (यह जनरेटर की तरह लग सकता है लेकिन आलसी मूल्यांकन की अवधारणा है) विभिन्न)।
एक उदाहरण के रूप में, निम्नलिखित पर विचार करें:
# Python 2.x
>>> a = range(10)
>>> type(a)
<type 'list'>
>>> b = xrange(10)
>>> type(b)
<type 'xrange'>
तथा
# Python 3.x
>>> a = range(10)
>>> type(a)
<class 'range'>
इस पोस्ट को देखेंश्रेणी और xrange के बीच अंतर :
उद्धरण के लिए:
range
रिटर्न वही है जो आप सोचते हैं: निरंतर पूर्णांक की एक सूची, एक परिभाषित लंबाई की शुरुआत 0. के साथxrange
, हालांकि, एक "xrange ऑब्जेक्ट" लौटाता है , जो एक इट्रेटर की तरह एक महान सौदा कार्य करता है
xrange
एक पुनरावृत्ति नहीं है। इसके द्वारा दी गई सूची range
पुनरावृति का समर्थन करती है (एक सूची एक पुनरावृत्त के प्रोटोटाइप उदाहरण है)। का समग्र लाभ xrange
"न्यूनतम" नहीं है। और इसी तरह।