2012-07-20 15 views
35

मैं तथ्य यह है कि numpy सरणियों कई स्थानों पर संदर्भ द्वारा पारित कर रहे हैं, लेकिन फिर जब मैं निम्नलिखित कोड निष्पादित, क्यों foo के व्यवहार और barसंदर्भ द्वारा पारित numpy arrays हैं?

import numpy as np 

def foo(arr): 
    arr = arr - 3 

def bar(arr): 
    arr -= 3 

a = np.array([3, 4, 5]) 
foo(a) 
print a # prints [3, 4, 5] 

bar(a) 
print a # prints [0, 1, 2] 

के बीच एक अंतर मैं उपयोग कर रहा हूँ है भर में आया था पायथन 2.7 और numpy संस्करण 1.6.1

+1

संबंधित: http://stackoverflow.com/q/9047111/166749 –

+0

यह बात पाइथन कॉल "संदर्भ" के पास पास-बाय-रेफरेंस के साथ कुछ लेना देना नहीं है, यही कारण है कि। – delnan

उत्तर

46

पायथन में, all variable names are references to values

जब पायथन एक असाइनमेंट का मूल्यांकन करता है, the right-hand side is evaluated before the left-hand sidearr - 3 एक नई सरणी बनाता है; यह arr जगह में संशोधित नहीं करता है।

arr = arr - 3 स्थानीय चर arr इस नई सरणी को संदर्भित करता है। यह मूल रूप से arr द्वारा संदर्भित मान को संशोधित नहीं करता है जो foo पर पारित किया गया था। परिवर्तनीय नाम arr बस नई सरणी, arr - 3 पर बाध्य हो जाता है। इसके अलावा, arrfoo फ़ंक्शन के दायरे में स्थानीय चर नाम है। एक बार foo फ़ंक्शन पूरा हो जाने पर, arr पर कोई और संदर्भ नहीं है और पाइथन कचरे के लिए स्वतंत्र है, जो संदर्भों को संदर्भित करता है। As Reti43 points out, arr के मूल्य के लिए आदेश a को प्रभावित करने के लिए, fooarr लौटना चाहिए और a कि मूल्य को सौंपा जाना चाहिए:

def foo(arr): 
    arr = arr - 3 
    return arr 
    # or simply combine both lines into `return arr - 3` 

a = foo(a) 

इसके विपरीत, arr -= 3, जो अजगर __iadd__ special method के लिए एक कॉल में तब्दील हो, संशोधित करता है arr द्वारा संदर्भित सरणी।

+6

जो कि तरह का, अनजान है ... – Mehdi

+0

और इसलिए, 'foo()' के प्रभाव के लिए, इसे 'arr' वापस करने की आवश्यकता है और उस कोड में जिसे आप इसे' a = foo (a) ' । – Reti43

+0

प्रतीक्षा करें ताकि वस्तुएं पाइथन में कार्यों के संदर्भ में पारित हो जाएं ...? –

8

पहले समारोह (arr - 3) की गणना करता है, तो स्थानीय नाम प्रदान करती है यह करने के लिए arr, में पारित सरणी डेटा को प्रभावित नहीं करता है। मेरा अनुमान है कि दूसरे समारोह में, np.array-= ऑपरेटर को ओवरराइड करता है, और उसके स्थान पर ही चल रही है सरणी डेटा।

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