2010-01-24 13 views
5

तो, सीपीथन (2.4) में कुछ रोचक व्यवहार होता है जब कुछ की लंबाई 1 < < 32 (एक int का आकार) के करीब होती है।पाइथन, लेन, और इनट्स का आकार

r = xrange(1<<30) 
assert len(r) == 1<<30 

ठीक है, लेकिन:

r = xrange(1<<32) 
assert len(r) == 1<<32 
ValueError: xrange object size cannot be reported`__len__() should return 0 <= outcome 

एलेक्स के wowrange इस व्यवहार भी है। wowrange(1<<32).l ठीक है, लेकिन len(wowrange(1<<32)) खराब है। मुझे लगता है कि यहां कुछ चलने वाले बिंदु व्यवहार (नकारात्मक के रूप में पढ़ा जा रहा है) कार्रवाई चल रही है।

  1. वास्तव में यहाँ क्या हो रहा है क्या? (यह नीचे बहुत अच्छी तरह से हल किया गया है!)
  2. मैं इसके आसपास कैसे हो सकता हूं? लंबे समय तक?

(मेरे विशिष्ट अनुप्रयोग random.sample(xrange(1<<32),ABUNCH)) अगर लोगों को सीधे उस प्रश्न को सुलझाने के लिए चाहते है!)

+0

@Gregg, मजाकिया है कि मुझे ValueError के बजाय ओवरफ्लो त्रुटि मिलती है (जैसा कि स्वीकृत ए को उस क्यू में है), लेकिन, कम से कम। समस्या यह है कि, आपके विशिष्ट एप्लिकेशन के लिए, आप एक 'random.sample' चाहते हैं जो स्मृति में फिट नहीं हो सकता है - लेकिन प्रत्येक पायथन संरचना ** ** स्मृति में फिट होना चाहिए। यदि आप एक और क्यू खोलते हैं और पैरामीटर को अधिक विस्तार से निर्दिष्ट करते हैं तो शायद यह विशिष्ट व्यावहारिक सहायता प्रदान करने के लिए अधिक व्यावहारिक है ... –

+0

@Alex, वास्तव में, नमूना को स्मृति में फिट नहीं होना चाहिए, लेकिन 2.4 में (मुझे पता है, पुरानी खबर!) यादृच्छिक मॉड्यूल, यह एक लेन() कॉल करता है जो विफल रहता है! xrange (1 << 32) स्वयं ठीक है, लेकिन कॉल: एन = लेन (जनसंख्या) मॉड्यूल के 29 9 पर नहीं है। –

+0

'random.sample' को पायथन 2.5, 2.6, 3.0 और 3.1 में भी लैन()' कॉल करने की आवश्यकता है, और यह कॉल प्रत्येक संस्करण में 'xrange (1 << 32)' पर विफल रहता है (क्योंकि 'len() 'केवल उन कंटेनरों पर लागू होता है जो "स्मृति में फिट" होते हैं और' xrange' अवधारणात्मक रूप से नहीं)। तो यदि आप बेहतर निर्दिष्ट करते हैं कि आपको वास्तव में क्या चाहिए, तो esp। 'ABUNCH' के लिए एक सामान्य मूल्य क्या है, हम सुझाव दे सकते हैं कि' random.sample' की इस सीमा के आसपास कैसे काम करें (जो आसपास के _all_ पायथन संस्करणों पर लागू होता है!)। एक अलग क्यू, आईएमएचओ में बेहतर प्रदर्शन किया। –

उत्तर

11

CPython मानता है कि सूचियों स्मृति में फिट। यह उन ऑब्जेक्ट्स तक फैला हुआ है जो सूचियों जैसे व्यवहार करते हैं, जैसे xrange। अनिवार्य रूप से, len फ़ंक्शन __len__ विधि को size_t में कनवर्ट करने योग्य कुछ वापस करने की अपेक्षा करता है, जो तब नहीं होगा जब तार्किक तत्वों की संख्या बहुत बड़ी हो, भले ही वे तत्व वास्तव में स्मृति में मौजूद न हों।

+0

यह बताने के लिए धन्यवाद कि विशेष रूप से 'लेन' इस तरह से क्यों व्यवहार कर रहा है। cpython लेन 'size_t' की अपेक्षा करता है। –

+0

माइनर क्विबल: सिर्फ इसलिए कि 'size_t' के लिए लंबाई बहुत बड़ी है इसका मतलब यह नहीं है कि ऑब्जेक्ट स्मृति में फिट नहीं है। उदाहरण के लिए मेरे पास एक बिट फ़ील्ड का प्रतिनिधित्व करने वाला वर्ग है जिसके लिए '__len__' 32-बिट पायथन में 256MB से अधिक वस्तुओं के लिए काम करना बंद कर देता है। –

1

1<<32, जब एक हस्ताक्षरित पूर्णांक के रूप में इलाज, नकारात्मक है।

5

आप पाएंगे कि

xrange(1 << 31 - 1) 

पिछले एक बर्ताव करता है कि के रूप में आप चाहते हैं। , 1.

1 << 32 नहीं है एक सकारात्मक 32-बिट पूर्णांक (पायथन के int डेटाप्रकार) पर हस्ताक्षर किए, ताकि तुम क्यों कि त्रुटि हो रही है है - इसका कारण यह है अधिकतम पर हस्ताक्षर किए है (32-बिट) पूर्णांक 2^31 है।

पायथन 2.6 में, मैं बिना किसी त्रुटि के xrange(1 << 32) या xrange(1 << 31) भी नहीं कर सकता, परिणामस्वरूप बहुत कम len

संपादित आप थोड़ा और विस्तार चाहते हैं ...

1 << 31 संख्या 0x80000000 जो 2 के पूरक प्रतिनिधित्व में एक 32-बिट के लिए सबसे कम प्रदर्शनीय नकारात्मक संख्या (-1 * 2^31) है का प्रतिनिधित्व करता है int। तो हां, जिन संख्याओं के साथ आप काम कर रहे हैं, उनके बिट-वार प्रतिनिधित्व के कारण, यह वास्तव में नकारात्मक हो रहा है।

32-बिट 2 के पूरक संख्या के लिए, 0x7FFFFFFF नकारात्मक संख्याओं में "ओवरफ़्लो" से पहले उच्चतम प्रतिनिधित्व करने योग्य पूर्णांक (2^31 - 1) है।

Further reading, यदि आप रुचि रखते हैं।

ध्यान दें कि जब आप प्रॉम्प्ट में 2147483648L की तरह कुछ देखते हैं, तो अंत में "एल" इंगित करता है कि अब इसे "लंबे पूर्णांक" के रूप में दर्शाया जा रहा है (64 बिट्स, आमतौर पर, मैं इस पर कोई वादा नहीं कर सकता पायथन इसे संभालता है क्योंकि मैंने इसे पढ़ा नहीं है)।

+1

'हेक्स (1 << 32)' आज़माएं और देखें कि आपको क्या मिलता है। संकेत: यह 0x80000000 नहीं है। –

+0

टाइपो, क्षमा करें, तय करें। – Sapph

संबंधित मुद्दे