मैं एक फ़ंक्शन से कई मान कैसे लौटाऊं? [बन्द है]


1067

भाषाओं में कई मूल्यों को वापस लाने के लिए विहित तरीका जो इसका समर्थन करता है वह अक्सर तुच्छ होता है

विकल्प: ट्यूपल का उपयोग करना

इस तुच्छ उदाहरण पर विचार करें:

def f(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return (y0, y1, y2)

हालांकि, यह जल्दी से समस्याग्रस्त हो जाता है क्योंकि मूल्यों की संख्या बढ़ जाती है। यदि आप चार या पाँच मान वापस करना चाहते हैं तो क्या होगा? ज़रूर, आप उन्हें टपका सकते हैं, लेकिन यह भूलना आसान है कि कौन सा मूल्य कहाँ है। आप उन्हें प्राप्त करना चाहते हैं, जहां भी उन्हें अनपैक करना बल्कि बदसूरत है।

विकल्प: एक शब्दकोश का उपयोग करना

लगता है कि अगला तार्किक कदम किसी तरह के 'रिकॉर्ड नोटेशन' को पेश करेगा। पायथन में, ऐसा करने का स्पष्ट तरीका ए है dict

निम्नलिखित को धयान मे रखते हुए:

def g(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return {'y0': y0, 'y1': y1 ,'y2': y2}

(बस स्पष्ट होने के लिए, y0, y1 और y2 केवल सार पहचानकर्ता के रूप में हैं। जैसा कि बताया गया है, व्यवहार में आप सार्थक पहचानकर्ताओं का उपयोग करेंगे।)

अब, हमारे पास एक ऐसा तंत्र है जिससे हम लौटे हुए ऑब्जेक्ट के किसी विशेष सदस्य को प्रोजेक्ट कर सकते हैं। उदाहरण के लिए,

result['y0']

विकल्प: कक्षा का उपयोग करना

हालांकि, एक और विकल्प है। हम इसके बजाय एक विशेष संरचना वापस कर सकते हैं। मैंने इसे पायथन के संदर्भ में फंसाया है, लेकिन मुझे यकीन है कि यह अन्य भाषाओं पर भी लागू होता है। वास्तव में, यदि आप C में काम कर रहे थे तो यह आपके लिए एकमात्र विकल्प हो सकता है। यहाँ जाता हैं:

class ReturnValue:
  def __init__(self, y0, y1, y2):
     self.y0 = y0
     self.y1 = y1
     self.y2 = y2

def g(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return ReturnValue(y0, y1, y2)

पायथन में पिछले दो शायद नलसाजी के संदर्भ में बहुत समान हैं - आखिरकार { y0, y1, y2 }आंतरिक में प्रविष्टियां होने __dict__के बाद ReturnValue

पायथन द्वारा प्रदान की गई एक अतिरिक्त विशेषता है, हालांकि छोटी वस्तुओं के लिए, __slots__विशेषता। वर्ग के रूप में व्यक्त किया जा सकता है:

class ReturnValue(object):
  __slots__ = ["y0", "y1", "y2"]
  def __init__(self, y0, y1, y2):
     self.y0 = y0
     self.y1 = y1
     self.y2 = y2

से अजगर संदर्भ मैनुअल :

__slots__घोषणा हर चर के लिए एक मूल्य धारण करने के लिए प्रत्येक उदाहरण में उदाहरण चर और भंडार सिर्फ पर्याप्त जगह का एक अनुक्रम लेता है। अंतरिक्ष सहेजा गया है क्योंकि __dict__प्रत्येक उदाहरण के लिए नहीं बनाया गया है।

विकल्प: डेटाकल्स का उपयोग करना (पायथन 3.7+)

पायथॉन 3.7 के नए डेटास्केल्स का उपयोग करते हुए, एक वर्ग को स्वचालित रूप से जोड़े गए विशेष तरीकों, टाइपिंग और अन्य उपयोगी टूल के साथ लौटाएं:

@dataclass
class Returnvalue:
    y0: int
    y1: float
    y3: int

def total_cost(x):
    y0 = x + 1
    y1 = x * 3
    y2 = y0 ** y3
    return ReturnValue(y0, y1, y2)

विकल्प: किसी सूची का उपयोग करना

एक और सुझाव जिसे मैंने अनदेखा किया वह बिल द छिपकली से आता है:

def h(x):
  result = [x + 1]
  result.append(x * 3)
  result.append(y0 ** y3)
  return result

हालांकि यह मेरी सबसे कम पसंदीदा विधि है। मुझे लगता है कि मैं हास्केल के संपर्क में हूं, लेकिन मिश्रित प्रकार की सूचियों का विचार मुझे हमेशा असहज लगा। इस विशेष उदाहरण में सूची -not- मिश्रित प्रकार है, लेकिन यह बोधगम्य हो सकता है।

इस तरह से इस्तेमाल की जाने वाली एक सूची वास्तव में टपल के संबंध में कुछ भी हासिल नहीं करती है जहां तक ​​मैं बता सकता हूं। अजगर में सूचियों और tuples के बीच केवल वास्तविक अंतर यह है कि सूचियों हैं परिवर्तनशील है, जबकि tuples नहीं हैं।

मैं व्यक्तिगत रूप से कार्यात्मक प्रोग्रामिंग से सम्मेलनों को आगे बढ़ाता हूं: एक ही प्रकार के तत्वों की किसी भी संख्या के लिए सूचियों का उपयोग करें, और पूर्व निर्धारित प्रकार के तत्वों की निश्चित संख्या के लिए ट्यूपल्स।

सवाल

लंबी प्रस्तावना के बाद, अपरिहार्य प्रश्न आता है। कौन सा तरीका (आपको लगता है) सबसे अच्छा है?


10
आपके द्वारा दिए गए उत्कृष्ट उदाहरणों में आप परिवर्तनशील का उपयोग करते हैं y3, लेकिन जब तक y3 को वैश्विक घोषित नहीं किया जाता है, यह NameError: global name 'y3' is not definedशायद सिर्फ उपयोग होगा 3?
1949

11
महान उत्तरों के साथ कई शानदार प्रश्न बंद हो जाते हैं क्योंकि 'राय' कीवर्ड उत्पन्न होता है। आप तर्क दे सकते हैं कि संपूर्ण एसओ राय पर आधारित है, लेकिन यह तथ्यों, संदर्भों और विशिष्ट विशेषज्ञता द्वारा सूचित राय है। सिर्फ इसलिए कि कोई व्यक्ति "जो आपको लगता है कि सबसे अच्छा है" पूछता है, इसका मतलब यह नहीं है कि वे वास्तविक दुनिया के तथ्यों, संदर्भों और विशिष्ट विशेषज्ञता से अलग व्यक्तिगत राय पूछ रहे हैं। वे लगभग निश्चित रूप से उस तरह की राय के लिए पूछ रहे हैं, जिस तरह से पूरी तरह से आधारित है, और उस व्यक्ति, जो राय बनाने के लिए उपयोग किया जाता है, तथ्यों, संदर्भों और विशिष्ट विशेषज्ञता के साथ दस्तावेज किया गया है।
नील

@hetepeperfan को 3 को बदलने की आवश्यकता नहीं है, और न ही वैश्विक में y3 को परिभाषित कर रहा है, आप एक स्थानीय नाम का भी उपयोग कर सकते y3हैं, वही काम भी करेगा।
ओकी

जवाबों:


637

इस उद्देश्य के लिए 2.6 में नामित ट्यूपल्स जोड़े गए थे। इसी तरह के बिलिन उदाहरण के लिए os.stat भी देखें ।

>>> import collections
>>> Point = collections.namedtuple('Point', ['x', 'y'])
>>> p = Point(1, y=2)
>>> p.x, p.y
1 2
>>> p[0], p[1]
1 2

पायथन 3 (3.6+, मुझे लगता है) के हाल के संस्करणों में, नई typingलाइब्रेरी को NamedTupleटुपल्स बनाने और अधिक शक्तिशाली बनाने के लिए आसान ट्यूपल्स बनाने के लिए क्लास मिला । इनहेरिट करने से typing.NamedTupleआप डॉकस्ट्रिंग, डिफ़ॉल्ट मान और एनोटेशन का उपयोग कर सकते हैं।

उदाहरण (डॉक्स से):

class Employee(NamedTuple):  # inherit from typing.NamedTuple
    name: str
    id: int = 3  # default value

employee = Employee('Guido')
assert employee.id == 3

68
यह केवल सही उत्तर है क्योंकि यह एकमात्र विहित संरचना है जिसे ओपी ने नहीं माना था और क्योंकि यह लंबे ट्यूपल्स के प्रबंधन की उनकी समस्या को संबोधित करता है। के रूप में चिह्नित किया जाना चाहिए।
हवाई

7
ठीक है, बड़े पैमाने पर परिणामों के namedtupleलिए एक छोटा मेमोरी फुटप्रिंट है (ट्यूबल की लंबी सूची, जैसे डीबी जस्टिस के परिणाम)। अलग-अलग मदों के लिए (यदि प्रश्न में फ़ंक्शन को अक्सर नहीं कहा जाता है) शब्दकोशों और कक्षाएं ठीक भी हैं। लेकिन नेमटुपल्स इस मामले में एक अच्छा / अच्छा समाधान है।
लुत्ज प्रेचल

8
@wom: यह मत करो। पायथन namedtupleपरिभाषाओं को विशिष्ट बनाने के लिए कोई प्रयास नहीं करता है (प्रत्येक कॉल एक नया बनाता है), namedtupleसीपीयू और मेमोरी दोनों में वर्ग अपेक्षाकृत महंगा है, और सभी वर्ग परिभाषाएं आंतरिक रूप से चक्रीय संदर्भों को शामिल करती हैं (इसलिए CPython पर, आप चक्रीय जीसी रन की प्रतीक्षा कर रहे हैं उनके लिए जारी किया जाएगा)। यह pickleवर्ग के लिए भी असंभव बनाता है (और इसलिए, multiprocessingज्यादातर मामलों में उदाहरणों का उपयोग करना असंभव है )। मेरी 3.6.4 x64 पर कक्षा की प्रत्येक रचना ~ 0.337 एमएस की खपत करती है, और 1 केबीएम मेमोरी के नीचे बस जाती है, जिससे आपके उदाहरण की बचत होती है।
शैडो रेंजर

3
मैं ध्यान दूंगा, पायथन 3.7 ने नई namedtupleकक्षाएं बनाने की गति में सुधार किया ; सीपीयू की लागत लगभग 4x के एक कारक से कम हो जाती है , लेकिन वे अभी भी एक उदाहरण बनाने के लिए लागत की तुलना में लगभग 1000 गुना अधिक हैं, और प्रत्येक वर्ग के लिए मेमोरी लागत अधिक बनी हुई है ("1 केबी के तहत" मेरी पिछली टिप्पणी में गलत था " वर्ग के लिए, _sourceआम तौर पर केवल 1.5 KB है, _sourceइसे 3.7 में हटा दिया गया है, इसलिए यह संभावित रूप से 1 केबीए प्रति प्लेट के नीचे मूल दावे के करीब है)।
शैडो रेंजर

4
@SergeStroobandt - यह मानक पुस्तकालय का एक हिस्सा है, सिर्फ एक बिल्डिन नहीं है। आपको यह चिंता करने की आवश्यकता नहीं है कि यह पायथन> = 2.6 के साथ किसी अन्य सिस्टम पर स्थापित नहीं हो सकता है। या क्या आपको कोड की अतिरिक्त लाइन पर आपत्ति है?
जस्टिन

234

छोटी परियोजनाओं के लिए मुझे ट्यूपल्स के साथ काम करना सबसे आसान लगता है। जब मुझे प्रबंधित करने में बहुत मुश्किल हो जाती है (और पहले नहीं) तो मैं तार्किक संरचनाओं में चीजों को समूहित करना शुरू करता हूं, हालांकि मुझे लगता है कि आपके सुझाए गए शब्दों और ReturnValueवस्तुओं का उपयोग गलत है (या बहुत सरल)।

कुंजी के साथ एक शब्दकोश रिटर्निंग "y0", "y1", "y2", आदि tuples की किसी भी लाभ प्रदान नहीं करता है। एक रिटर्निंग ReturnValueगुणों के साथ उदाहरण .y0, .y1, .y2, आदि tuples की किसी भी लाभ या तो प्रदान नहीं करता है। यदि आप कहीं भी जाना चाहते हैं, तो आपको चीजों का नामकरण शुरू करने की आवश्यकता है, और आप यह कर सकते हैं कि आप वैसे भी tuples का उपयोग कर सकते हैं:

def get_image_data(filename):
    [snip]
    return size, (format, version, compression), (width,height)

size, type, dimensions = get_image_data(x)

IMHO, ट्यूपल्स से परे एकमात्र अच्छी तकनीक वास्तविक वस्तुओं को उचित तरीकों और गुणों के साथ वापस करना है, जैसे आप से re.match()या open(file)


6
प्रश्न - वहाँ के बीच कोई अंतर है size, type, dimensions = getImageData(x)और (size, type, dimensions) = getImageData(x)? यानी, एक टफल्ड असाइनमेंट के बाएं-किनारे को लपेटने से कोई फर्क पड़ता है?
Reb.Cabin

11
@ Reb.Cabin कोई अंतर नहीं है। टपल की पहचान अल्पविराम द्वारा की जाती है और कोष्ठक का उपयोग केवल चीजों को एक साथ समूहित करने के लिए होता है। उदाहरण के लिए (1)एक पूर्णांक है, जबकि (1,)या 1,एक टपल है।
फिल

19
"चाबियाँ y0, y1, y2 आदि के साथ एक शब्दकोश लौटाना tuples पर कोई लाभ प्रदान नहीं करता है": शब्दकोश में यह फायदा है कि आप मौजूदा कोड को तोड़े बिना दिए गए शब्दकोश में फ़ील्ड जोड़ सकते हैं।
ostrokach

"चाबियाँ y0, y1, y2 आदि के साथ एक शब्दकोश लौटाना ट्यूपल्स पर कोई लाभ नहीं देता है": यह स्थिति के बजाय इसके नाम के आधार पर डेटा तक पहुंचने के साथ अधिक पठनीय और कम त्रुटि वाला प्रवण है।
डेनिस डॉलफस

204

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

def f():
    return True, False
x, y = f()
print(x)
print(y)

देता है:

True
False

24
आप अभी भी एक संग्रह लौटा रहे हैं। यह एक टपल है। मैं इसे और अधिक स्पष्ट करने के लिए कोष्ठक पसंद करता हूं। यह कोशिश करें: type(f())रिटर्न <class 'tuple'>
इगोर

20
@ आईओआरजी: tupleपहलू को स्पष्ट करने का कोई कारण नहीं है ; यह वास्तव में महत्वपूर्ण नहीं है कि आप एक लौट रहे हैं tuple, यह कई मूल्यों की अवधि को लौटाने के लिए मुहावरा है। समान कारण आप स्वैप मुहावरे x, y = y, x, कई आरंभीकरण x, y = 0, 1, आदि के साथ पार्न्स को छोड़ देते हैं ; यकीन है, यह tupleहुड के नीचे बनाता है , लेकिन यह स्पष्ट करने का कोई कारण नहीं है, क्योंकि tupleएस बिल्कुल भी बात नहीं है। पायथन ट्यूटोरियल कई असाइनमेंट का परिचय देता है इससे पहले कि यह tupleएस पर भी छूता है ।
शैडो रेंजर

@ShadowRanger मानों के किसी भी क्रम को दाहिने हाथ की तरफ अल्पविराम से अलग करके =पायथन में या उनके आसपास कोष्ठक के बिना एक ट्यूपल है। तो वास्तव में यहाँ कोई स्पष्ट या निहित नहीं है। a, b, c एक tuple जितना (a, b, c) है। जब आप इस तरह के मूल्यों को वापस करते हैं, तो "हुड के नीचे" टपल का कोई निर्माण नहीं होता है, क्योंकि यह केवल एक साधारण सरल टपल है। ओपी ने पहले ही ट्यूपल्स का उल्लेख किया है, इसलिए वास्तव में उसने जो उल्लेख किया है और यह उत्तर दिखाता है, उसके बीच कोई अंतर नहीं है। कोई नहीं
Ken4scholars

2
यह शाब्दिक पहला विकल्प है जो प्रश्न में सुझाया गया है
एंडोलिथ

1
@endolith दो बार आदमी एक सवाल पूछता है ("मैं कई मूल्यों को कैसे वापस कर सकता हूं?" और " आप कई मूल्यों को कैसे लौटाते हैं?") इस उत्तर द्वारा दिए गए हैं। प्रश्न का पाठ कभी-कभी बदल गया है। और यह एक राय आधारित प्रश्न है।
जोसेफ हेंसन

74

मैं डिक्शनरी के लिए वोट करता हूं।

मुझे लगता है कि अगर मैं एक ऐसा कार्य करता हूं जो 2-3 से अधिक चर देता है तो मैं उन्हें एक शब्दकोश में बदल दूंगा। अन्यथा मैं जो कुछ भी वापस कर रहा हूं उसके आदेश और सामग्री को भूल जाता हूं।

इसके अलावा, एक 'विशेष' संरचना शुरू करने से आपके कोड का पालन करना अधिक कठिन हो जाता है। (किसी और को यह जानने के लिए कोड के माध्यम से खोजना होगा कि यह क्या है)

यदि आपका संबंधित प्रकार दिखता है, तो उदाहरण के लिए, वर्णनात्मक शब्दकोश कुंजियों का उपयोग करें, 'x-values ​​list'।

def g(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return {'y0':y0, 'y1':y1 ,'y2':y2 }

5
प्रोग्रामिंग के कई वर्षों के बाद, मैं उस ओर जाता हूं जो कभी भी डेटा और फ़ंक्शन की संरचना की आवश्यकता होती है। सबसे पहले, आप हमेशा आवश्यक के रूप में रिफ्लेक्टर कर सकते हैं।
मोनकुट

हम कई बार फ़ंक्शन को कॉल किए बिना शब्दकोश के भीतर मान कैसे प्राप्त करेंगे? उदाहरण के लिए, यदि मैं एक अलग फ़ंक्शन में y1 और y3 का उपयोग करना चाहता हूं?
मैट

3
परिणामों को एक अलग चर पर असाइन करें। result = g(x); other_function(result)
1

1
@monkut हाँ। इस तरह से कई कार्यों को परिणाम पारित करने की अनुमति मिलती है, जो हर बार परिणाम के विशेष भागों को विशेष रूप से संदर्भित किए बिना, परिणाम से अलग-अलग आर्ग लेते हैं।
ग्नूडीफ

38

एक और विकल्प जनरेटर का उपयोग होगा:

>>> def f(x):
        y0 = x + 1
        yield y0
        yield x * 3
        yield y0 ** 4


>>> a, b, c = f(5)
>>> a
6
>>> b
15
>>> c
1296

हालांकि IMHO टुपल्स आमतौर पर सबसे अच्छे होते हैं, सिवाय उन मामलों में जहां वापस लौटाए जा रहे मूल्य एक वर्ग में एनकैप्सुलेशन के लिए उम्मीदवार हैं।


1
यह सबसे साफ समाधान लगता है, और इसमें एक साफ वाक्यविन्यास है। क्या इसमें कोई कमी है? यदि आप सभी रिटर्न का उपयोग नहीं करते हैं, तो क्या आपको नुकसान पहुंचाने के लिए 'अनपेक्षित' पैदावार मिल रही है?
१६:१५ को १४:३०

24
यह "साफ" हो सकता है, लेकिन यह बिल्कुल सहज नहीं लगता है। कैसे कोई है जो इस पैटर्न का सामना करने से पहले कभी नहीं जानता होगा कि स्वचालित ट्यूपल अनपैकिंग करना प्रत्येक को ट्रिगर करेगा yield?
coredumperror

1
@CoreDumpError, जनरेटर सिर्फ यही हैं ... जनरेटर। def f(x): …; yield b; yield a; yield rबनाम के बीच कोई बाहरी अंतर नहीं है (g for g in [b, a, r]), और दोनों आसानी से सूचियों या ट्यूपल्स में परिवर्तित हो जाएंगे, और इस तरह से ट्यूपल अनपैकिंग का समर्थन करेंगे। टपल जनरेटर फॉर्म एक कार्यात्मक दृष्टिकोण का अनुसरण करता है, जबकि फ़ंक्शन फॉर्म जरूरी है और प्रवाह नियंत्रण और चर असाइनमेंट की अनुमति देगा।
स्लीपब्लांक

30

जब भी कोई ट्यूल "प्राकृतिक" महसूस करता है, मैं टुपल्स का उपयोग करना पसंद करता हूं; निर्देशांक एक विशिष्ट उदाहरण है, जहां अलग-अलग वस्तुएं अपने दम पर खड़ी हो सकती हैं, जैसे कि एक-अक्ष में केवल स्केलिंग गणना, और आदेश महत्वपूर्ण है। नोट: यदि मैं समूह के अर्थ पर प्रतिकूल प्रभाव के बिना वस्तुओं को सॉर्ट या फेरबदल कर सकता हूं, तो मुझे संभवतः एक टपल का उपयोग नहीं करना चाहिए।

मैं केवल एक वापसी मान के रूप में शब्दकोशों का उपयोग करता हूं, जब समूहीकृत वस्तुएं हमेशा समान नहीं होती हैं। वैकल्पिक ईमेल हेडर सोचो।

बाकी मामलों के लिए, जहां समूहित वस्तुओं का समूह के अंदर निहित अर्थ है या अपने स्वयं के तरीकों के साथ पूरी तरह से विकसित वस्तु की आवश्यकता है, मैं एक वर्ग का उपयोग करता हूं।


29

मैं पसंद करता हूं:

def g(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return {'y0':y0, 'y1':y1 ,'y2':y2 }

ऐसा लगता है कि बाकी सब कुछ एक ही काम करने के लिए अतिरिक्त कोड है।


22
Tuples को अनपैक करना आसान होता है: y0, y1, y2 = g () आपको जो करना है उसके साथ: result = g () y0, y1, y2 = result.get ('y0'), result.get ('y1') ), result.get ('y2') जो थोड़ा बदसूरत है। प्रत्येक समाधान में इसके 'प्लसस' और इसके 'मिनस' होते हैं।
ओली

27
>>> def func():
...    return [1,2,3]
...
>>> a,b,c = func()
>>> a
1
>>> b
2
>>> c
3

@ एडवर्ड नहीं, यह नहीं है, यह एक सूची नहीं टपल देता है।
साइमन हिब्स

1
विनाशकारी मेरी राय में सूची वापस करने का तर्क है
सेमीोमेंट

21

आम तौर पर, "विशेष संरचना" वास्तव में किसी वस्तु की समझदार वर्तमान स्थिति है, अपने स्वयं के तरीकों के साथ।

class Some3SpaceThing(object):
  def __init__(self,x):
    self.g(x)
  def g(self,x):
    self.y0 = x + 1
    self.y1 = x * 3
    self.y2 = y0 ** y3

r = Some3SpaceThing( x )
r.y0
r.y1
r.y2

मुझे अनाम संरचनाओं के लिए नाम खोजना पसंद है जहाँ संभव हो। सार्थक नाम चीजों को अधिक स्पष्ट करते हैं।


20

पायथन के टुपल्स, डीकट्स और ऑब्जेक्ट प्रोग्रामर को छोटे डेटा संरचनाओं ("चीजों") के लिए औपचारिकता और सुविधा के बीच एक सहज व्यापार प्रदान करते हैं। मेरे लिए, किसी चीज़ का प्रतिनिधित्व करने का विकल्प मुख्य रूप से इस बात से निर्धारित होता है कि मैं संरचना का उपयोग कैसे करने जा रहा हूं। C ++ में, structडेटा-ओनली आइटम्स और classऑब्जेक्ट्स के लिए विधियों के साथ उपयोग करने के लिए यह एक सामान्य सम्मेलन है , भले ही आप कानूनी तौर पर ए में तरीके डाल सकते हैं struct; मेरी आदत पाइथन के समान है, dictऔर tupleइसके स्थान पर struct

समन्वय सेटों के लिए, मैं tupleएक बिंदु classया dict(और ध्यान दें कि आप tupleएक शब्दकोश कुंजी के रूप में उपयोग कर सकते हैं , इसलिए dictमहान विरल बहुआयामी सरणियों का उपयोग कर सकते हैं )।

अगर मैं चीजों की सूची पर पुनरावृत्त होने जा रहा हूं, तो मैं tupleपुनरावृत्ति पर पसंद करना चाहता हूं :

for score,id,name in scoreAllTheThings():
    if score > goodScoreThreshold:
        print "%6.3f #%6d %s"%(score,id,name)

... जैसा कि ऑब्जेक्ट संस्करण को पढ़ने के लिए अधिक बरबाद किया गया है:

for entry in scoreAllTheThings():
    if entry.score > goodScoreThreshold:
        print "%6.3f #%6d %s"%(entry.score,entry.id,entry.name)

... अकेले रहने दो dict

for entry in scoreAllTheThings():
    if entry['score'] > goodScoreThreshold:
        print "%6.3f #%6d %s"%(entry['score'],entry['id'],entry['name'])

यदि बात व्यापक रूप से उपयोग की जाती है, और आप अपने आप को कोड में कई स्थानों पर इस तरह के गैर-तुच्छ कार्यों को करते हुए पाते हैं, तो यह आमतौर पर उपयुक्त तरीकों के साथ एक वर्ग ऑब्जेक्ट बनाने के लिए सार्थक है।

अंत में, अगर मैं गैर-पायथन सिस्टम घटकों के साथ डेटा का आदान-प्रदान करने जा रहा हूं, तो मैं उन्हें अक्सर सबसे अधिक समय तक अपने पास रखूंगा, dictक्योंकि यह JSON क्रमांकन के लिए सबसे उपयुक्त है।


19

एक नामित कंटेनर वर्ग के S.Lott के सुझाव पर +1।

पायथन 2.6 और ऊपर के लिए, ए नामित टपल इन कंटेनर कक्षाओं को आसानी से बनाने का एक उपयोगी तरीका प्रदान करता है, और परिणाम "हल्के होते हैं और नियमित रूप से ट्यूपल्स की तुलना में अधिक मेमोरी की आवश्यकता नहीं होती है"।


4

पायथन जैसी भाषाओं में, मैं आमतौर पर एक शब्दकोश का उपयोग करता हूं क्योंकि इसमें एक नया वर्ग बनाने की तुलना में कम ओवरहेड शामिल है।

हालाँकि, अगर मैं खुद को लगातार वैरिएबल के एक ही सेट को वापस पाता हूं, तो शायद इसमें एक नया वर्ग शामिल है जिसे मैं कारक बनाऊंगा।


4

मैं फ़ंक्शन से मानों को पारित करने और वापस करने के लिए एक तानाशाही का उपयोग करूंगा:

चर फार्म का उपयोग करें के रूप में के रूप में परिभाषित प्रपत्र

form = {
    'level': 0,
    'points': 0,
    'game': {
        'name': ''
    }
}


def test(form):
    form['game']['name'] = 'My game!'
    form['level'] = 2

    return form

>>> print(test(form))
{u'game': {u'name': u'My game!'}, u'points': 0, u'level': 2}

यह मेरे लिए और प्रोसेसिंग यूनिट के लिए सबसे कारगर तरीका है।

आपको केवल एक पॉइंटर को पास करना होगा और केवल एक पॉइंटर को वापस करना होगा।

जब भी आप अपने कोड में बदलाव करते हैं तो आपको फ़ंक्शन (उनमें से हजारों) के तर्क बदलने की ज़रूरत नहीं है।


डायट्स परस्पर हैं। यदि आप किसी फ़ंक्शन के लिए एक तानाशाही पास करते हैं और वह फ़ंक्शन तानाशाही को संपादित करता है, तो परिवर्तन उस फ़ंक्शन के दायरे से बाहर दिखाई देंगे। समारोह के अंत में तानाशाह के लौटने का अर्थ यह हो सकता है कि फ़ंक्शन का कोई दुष्प्रभाव नहीं है, इसलिए मान को वापस नहीं किया जाना चाहिए, जिससे यह स्पष्ट हो testजाएगा कि मूल्य को सीधे संशोधित किया जाएगा। इसके साथ तुलना करें dict.update, जो एक मूल्य वापस नहीं करता है।
स्लीपब्लैंक

@sleblanc "फ़ंक्शन के अंत में तानाशाही लौटने का मतलब यह हो सकता है कि फ़ंक्शन का कोई दुष्प्रभाव नहीं है"। इसका मतलब यह नहीं है कि क्योंकि, जैसा कि आपने कहा, तानाशाही है। हालांकि, लौटने formसे न तो पठनीयता को नुकसान होता है और न ही प्रदर्शन को। ऐसे मामलों में जहां आपको सुधार करने की आवश्यकता हो सकती है form, इसे वापस करना [प्रपत्र] सुनिश्चित करता है कि अंतिम formवापस कर दिया गया है क्योंकि आप कहीं भी फॉर्म परिवर्तनों का ट्रैक नहीं रखेंगे।
एलिस ब्येरबी

3

"बेस्ट" आंशिक रूप से व्यक्तिपरक निर्णय है। सामान्य स्थिति में छोटे रिटर्न सेट के लिए टुपल्स का उपयोग करें जहां एक अपरिवर्तनीय स्वीकार्य है। एक ट्यूपल हमेशा एक सूची के लिए बेहतर होता है जब परिवर्तनशीलता की आवश्यकता नहीं होती है।

अधिक जटिल वापसी मूल्यों के लिए, या उस मामले के लिए जहां औपचारिकता मूल्यवान है (अर्थात उच्च मूल्य कोड) एक नामित टपल बेहतर है। सबसे जटिल मामले के लिए एक वस्तु आमतौर पर सबसे अच्छी होती है। हालाँकि, यह वास्तव में ऐसी स्थिति है जो मायने रखती है। यदि यह किसी वस्तु को वापस करने के लिए समझ में आता है क्योंकि वह वही है जो आप स्वाभाविक रूप से फ़ंक्शन के अंत में है (उदाहरण के लिए फैक्टरी पैटर्न) तो वस्तु वापस करें।

जैसा कि बुद्धिमान व्यक्ति ने कहा:

समयपूर्व अनुकूलन प्रोग्रामिंग में सभी बुराई (या कम से कम अधिकांश) की जड़ है।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.