2010-03-08 11 views
8

क्या पाइथन में एक सूची का मूल्यांकन किया जा सकता है?पायथन, आलसी सूची

उदाहरण के लिए

a = 1 
list = [a] 
print list 
#[1] 
a = 2 
print list 
#[1] 

सूची lazily तो मूल्यांकन करने के लिए स्थापित किया गया था, तो अंतिम पंक्ति होगा [2]

+0

यह वह नहीं है जो मुझे आलसी मूल्यांकन समझा गया है। मैं कहूंगा कि यह इस तरह है: हम पहले 30 सकारात्मक संख्याएं खोजना चाहते हैं जिनके वर्ग 3 से विभाजित हैं। उत्सुक भाषा के साथ, आप या तो प्रदर्शन के लिए कोड - 'जबकि (list.length <30) अगर (i * i % 3 == 0) सूची + = i ++; 'या अभिव्यक्ति (लेकिन रास्ते में भारी अनावश्यक सूचियों को फेंकना) -' सूची 1 = रेंज 0..10000; मैं सूची 1 में अगर मैं * i% 3 == 0 list2.add i; list2.trim (30) '।आलसी के साथ आप बाद वाले की तरह कुछ और लिखते हैं, लेकिन पूर्व के प्रदर्शन प्राप्त करते हैं। डैनियल ताओ [इसे शानदार ढंग से बताते हैं] (http://danieltao.com/lazy.js/)। –

+0

एक आलसी तरीका इस तरह दिख सकता है: 'रेंज() फ़िल्टर (var जहां var * var% 3 == 0)। टेक (30)' - यह बहुत स्पष्ट रूप से लिखा गया है, लेकिन कोड अनिवार्य रूप से नहीं चलाया जाता है। यह चलाया जाता है: 'श्रेणी' उत्पन्न करता है 1.' फ़िल्टर' - विफल रहता है क्योंकि '1 * 1% 3! = 0'। फिर 'रेंज' उत्पन्न करता है 2. 'फ़िल्टर' विफल रहता है। फिर 'रेंज' उत्पन्न करता है 3. 'फ़िल्टर' पास होता है क्योंकि '3 * 3% 3 == 0'। इसे ले लो 'इसे उत्तर के रूप में कतार दें। 'टेक' लेने के बाद 30 लिया गया है, एल्गोरिदम बंद हो जाता है। यह केवल उतनी मेमोरी का उपयोग करता है जितना इसकी आवश्यकता होती है, लेकिन यह भी अत्यधिक पठनीय (और समांतर) कोड है। –

उत्तर

10

"आलसी" मूल्यांकन की अवधारणा सामान्य रूप से कार्यात्मक भाषाओं के साथ आता है - लेकिन उन में आप एक ही पहचानकर्ता को दो अलग-अलग मानों को फिर से सौंप नहीं सकते थे, इसलिए, आपका उदाहरण पुन: उत्पन्न नहीं किया जा सका।

बिंदु पर सभी आलस्य के बारे में नहीं है - यह है कि एक पहचानकर्ता का उपयोग करते हुए एक ही मूल्य है कि पहचानकर्ता संदर्भित कर रहा है के लिए एक संदर्भ हो रही के समान होने की गारंटी है, और एक पहचानकर्ता फिर से बताए, एक नंगे नाम, एक अलग मूल्य के लिए, पहचानकर्ता को उनसे अलग मूल्य का संदर्भ देने की गारंटी दी जाती है। पहले मान (ऑब्जेक्ट) का संदर्भ खो नहीं गया है।

एक समान उदाहरण पर विचार करें जहां एक नंगे नाम पर फिर से असाइनमेंट खेल में नहीं है, बल्कि किसी अन्य प्रकार के उत्परिवर्तन (एक परिवर्तनीय वस्तु के लिए, निश्चित रूप से - संख्याएं और तार अपरिवर्तनीय हैं), जिसमें कुछ असाइनमेंट शामिल है बाकी एक नंगे नाम से:

>>> a = [1] 
>>> list = [a] 
>>> print list 
[[1]] 
>>> a[:] = [2] 
>>> print list 
[[2]] 

के बाद से कोई a - ... कि नंगे नाम a, बल्कि एक a[:] = ... कि a के सामग्री reassigns reassigns, यह अजगर के रूप में "सुस्त" बनाने के लिए तुच्छता आसान है जैसा आप चाहें (और वास्तव में ऐसा होगा मुझे इसे "उत्सुक" बनाने का प्रयास! -) ... यदि आलस्य बनाम उत्सुकता इन मामलों में से किसी के साथ कुछ भी करने के लिए थी (जो यह नहीं है ;-)।

बस (कुछ और है, जो नाना प्रकार से बदलाव किया जा सकता है और नियंत्रित उचित रूप से अपने स्वयं के प्रकार का उपयोग करके करने के लिए बताए बनाम) "एक नंगे नाम के बताए" की पूरी तरह से सरल अर्थ विज्ञान के बारे में पता हो सकता है, और बनाम "आलसी की दृष्टि भ्रम उत्सुक "उम्मीद है कि गायब हो सकता है ;-)

6

अजगर not really very lazy in general है।

आप आलसी डेटा संरचनाओं (जैसे अनंत सूचियों, et cetera) का अनुकरण करने के लिए जनरेटर का उपयोग कर सकते हैं, लेकिन जहां तक ​​सामान्य सूची वाक्यविन्यास, et cetera का उपयोग करने जैसी चीजें हैं, आपको आलस्य नहीं होगी।

1

वास्तविक आलसी सूची कार्यान्वयन की तलाश करते समय इस पोस्ट में आया, लेकिन यह कोशिश करने और काम करने के लिए एक मजेदार चीज की तरह लग रहा था।

निम्नलिखित कार्यान्वयन मूल रूप से क्या मूल रूप से करने के लिए कहा है गया था:

from collections import Sequence 

class LazyClosureSequence(Sequence): 
    def __init__(self, get_items): 
     self._get_items = get_items 

    def __getitem__(self, i): 
     return self._get_items()[i] 

    def __len__(self): 
     return len(self._get_items()) 

    def __repr__(self): 
     return repr(self._get_items()) 

आप इस तरह इसका इस्तेमाल:

>>> a = 1 
>>> l = LazyClosureSequence(lambda: [a]) 
>>> print l 
[1] 
>>> a = 2 
>>> print l 
[2] 

यह स्पष्ट रूप से भयानक है।

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