software - python tutorial




रिक्त सूची वाले डिफ़ॉल्ट पैरामीटर से बचने का अजगर तरीका क्या है? (4)

ऐसा नहीं है कि यह इस मामले में महत्वपूर्ण है, लेकिन आप किसी के लिए परीक्षण करने के लिए वस्तु पहचान का उपयोग कर सकते हैं:

if working_list is None: working_list = []

आप का फायदा भी उठा सकते हैं कि कैसे बुलियन ऑपरेटर या अजगर में परिभाषित किया गया है:

working_list = working_list or []

यद्यपि यह अप्रत्याशित रूप से व्यवहार करेगा यदि कॉलर आपको कार्य सूची के रूप में खाली सूची (जो कि झूठी के रूप में गिना जाता है) देता है और आपके फ़ंक्शन को उस सूची को संशोधित करने की उम्मीद करता है जिसने उसने इसे दिया था।

कभी-कभी यह एक सामान्य पैरामीटर वाला प्राकृतिक लगता है जो एक खाली सूची है। फिर भी अजगर इन स्थितियों में अप्रत्याशित व्यवहार प्रदान करता है।

उदाहरण के लिए, मेरे पास एक फ़ंक्शन है:

def myFunc(working_list = []):
    working_list.append("a")
    print working_list

पहली बार इसे डिफ़ॉल्ट के साथ कहा जाता है, काम करेगा, लेकिन उसके बाद कॉल लगातार अपडेट करने वाली सूची का उपयोग करेगा।

तो, मैं इच्छा के व्यवहार को पाने के लिए अजगर का तरीका क्या है (प्रत्येक कॉल पर एक ताजा सूची)?


def myFunc(working_list=None):
    if working_list is None: 
        working_list = []
    working_list.append("a")
    print working_list

मैं इसे कैसे करता हूं


पहले से ही अच्छे और सही उत्तर दिए गए हैं। मैं सिर्फ एक और सिंटैक्स को लिखना चाहता था कि आप क्या करना चाहते हैं जो मुझे अधिक सुंदर लगता है जब आप उदाहरण के लिए डिफ़ॉल्ट खाली सूचियों वाले वर्ग बनाना चाहते हैं:

class Node(object):
    def __init__(self, _id, val, parents=None, children=None):
        self.id = _id
        self.val = val
        self.parents = parents if parents is not None else []
        self.children = children if children is not None else []

यह स्निपेट अगर else ऑपरेटर सिंटैक्स का उपयोग करता है मुझे यह विशेष रूप से पसंद है क्योंकि यह एक बहुत कम एक-लाइनर बिना बृहदान्त्र आदि शामिल है और यह लगभग सामान्य अंग्रेज़ी वाक्य की तरह पढ़ता है। :)

आपके मामले में आप लिख सकते हैं

def myFunc(working_list=None):
    working_list = [] if working_list is None else working_list
    working_list.append("a")
    print working_list

यदि फ़ंक्शन का इरादा कार्य-सूची के रूप में पारित पैरामीटर को संशोधित करना है, तो हेनरीआर का उत्तर देखें (= कोई नहीं, कोई नहीं अंदर की जांच करें)

लेकिन यदि आप तर्क को बदलना नहीं चाहते थे, तो बस इसे सूची के लिए शुरुआती बिंदु के रूप में प्रयोग करें, आप बस इसे कॉपी कर सकते हैं:

def myFunc(starting_list = []):
    starting_list = list(starting_list)
    starting_list.append("a")
    print starting_list

(या इस सरल मामले में बस print starting_list + ["a"] सूची print starting_list + ["a"] लेकिन मुझे लगता है कि यह सिर्फ एक खिलौना उदाहरण था)

सामान्य तौर पर, अपने तर्क को बदलना पायथन में खराब शैली है। एकमात्र कार्य जो पूरी तरह से वस्तु को उत्परिवर्तित करने की अपेक्षा रखते हैं, वह वस्तुएं हैं। यह एक वैकल्पिक तर्क को बदलना भी दुर्लभ है - क्या एक साइड इफेक्ट होता है जो कुछ कॉलों में होता है, वास्तव में सबसे अच्छा इंटरफ़ेस होता है?

  • यदि आप इसे "आउटपुट आर्गुमेंट्स" की सी आदत से करते हैं, तो यह पूरी तरह से अनावश्यक है - आप टपल के रूप में हमेशा एक से अधिक मान लौटा सकते हैं

  • यदि आप इसे मध्यवर्ती सूचियों के निर्माण के बिना परिणाम की एक लंबी सूची बनाने के लिए करते हैं, तो इसे जनरेटर के रूप में लिखने और result_list.extend(myFunc()) का उपयोग करने पर result_list.extend(myFunc()) जब आप उसे बुला रहे हों। इस तरह से आपके फोन सम्मेलनों में बहुत साफ रहता है।

एक पैटर्न जहां एक वैकल्पिक एजीएल उत्परिवर्तित अक्सर किया जाता है, एक रिक्त "मेमो" आरसी रिकर्सिव फ़ंक्शंस में है:

def depth_first_walk_graph(graph, node, _visited=None):
    if _visited is None:
        _visited = set()  # create memo once in top-level call

    return if node in _visited
    _visited.add(node)
    for neighbour in graph[node]:
        depth_first_walk_graph(graph, neighbour, _visited)




python