लिखने का कॉम्पैक्ट तरीका (ए + बी == सी या ए + सी == बी या बी + सी == ए)


136

क्या बूलियन अभिव्यक्ति लिखने के लिए एक अधिक कॉम्पैक्ट या पायथोनिक तरीका है

a + b == c or a + c == b or b + c == a

मेरे द्वारा लाया गया

a + b + c in (2*a, 2*b, 2*c)

लेकिन यह थोड़ा अजीब है।


16
अधिक कॉम्पेक्ट? संभवतः। अधिक पायथोनिक? संभावना नहीं है।
chepner

126
अपने भविष्य को एक एहसान करो और इसे मूल रूप में रखो: यह एकमात्र ऐसा है जो तुरंत इस का उद्देश्य बताता है। कि संशोधित मत करो। "सरल जटिल से बेहतर है।", "पठनीयता मायने रखती है।" "यदि कार्यान्वयन को समझाना कठिन है, तो यह एक बुरा विचार है।"
प्रहार

21
पायथोनिक == अपठनीय?
नहरमन

3
@wwii वे परस्पर अनन्य नहीं हैं। A = 0, b = 0, c = 0;) देखें
होन्ज़ा ब्रेबेक

1
@Phresnel ने क्या कहा। अभिव्यक्ति को "सरल" करने की कोशिश करने के बजाय, इसे एक वर्णनात्मक नाम के साथ फ़ंक्शन में लपेटें।
सेफेलोपॉड

जवाबों:


206

यदि हम पायथन के ज़ेन को देखते हैं, तो मेरा जोर दें:

टिम पीटर्स द्वारा ज़ेन ऑफ़ पायथन

सुंदर बदसूरत से बेहतर है।
निहितार्थ की तुलना में स्पष्ट है।
सरल जटिल से बेहतर है।
कॉम्प्लेक्स जटिल से बेहतर है।
फ्लैट नेस्टेड से बेहतर है।
विरल घने से बेहतर है।
पठनीयता मायने रखती है।
नियम तोड़ने के लिए विशेष मामले पर्याप्त नहीं हैं।
यद्यपि व्यावहारिकता शुद्धता को हरा देती है।
त्रुटियों को कभी भी चुपचाप नहीं गुजरना चाहिए।
जब तक स्पष्ट रूप से चुप नहीं कराया जाता।
अस्पष्टता के सामने, अनुमान लगाने के प्रलोभन से इनकार करें।
वहाँ एक होना चाहिए - और अधिमानतः इसे करने के लिए केवल एक ही - स्पष्ट तरीका।
हालांकि यह तरीका पहली बार में स्पष्ट नहीं हो सकता जब तक कि आप डच न हों।
अब पहले से बेहतर है।
हालांकि कभी-कभी इससे बेहतर नहीं होता हैसही अब।
यदि कार्यान्वयन को समझाना कठिन है, तो यह एक बुरा विचार है।
यदि कार्यान्वयन की व्याख्या करना आसान है, तो यह एक अच्छा विचार हो सकता है।
नाम स्थान एक महान विचार का सम्मान कर रहे हैं - चलो उन में से अधिक करते हैं!

सबसे पाइथोनिक समाधान वह है जो स्पष्ट, सबसे सरल और सबसे आसान है:

a + b == c or a + c == b or b + c == a

इससे भी बेहतर, आपको इस कोड को समझने के लिए पायथन जानने की आवश्यकता नहीं है! यह इतना आसान है। यह, आरक्षण के बिना, सबसे अच्छा समाधान है। और कुछ भी बौद्धिक हस्तमैथुन है।

इसके अलावा, यह संभवतः सबसे अच्छा प्रदर्शन करने वाला समाधान है, क्योंकि यह सभी प्रस्तावों में से केवल एक है जो शॉर्ट सर्किट करता है। यदि a + b == c, केवल एक जोड़ और तुलना की जाती है।


11
इससे भी बेहतर, इरादे को स्पष्ट करने के लिए कुछ कोष्ठक में फेंक दें।
ब्रायन ओकले

3
कोष्ठक के बिना आशय पहले से ही स्पष्ट है। कोष्ठक को पढ़ना कठिन होगा - लेखक जब पहले से ही इसको कवर करता है तो कोष्ठक का उपयोग क्यों करता है?
मील्स राउत

1
बहुत चालाक होने की कोशिश करने के बारे में एक और नोट: आप उन अप्रत्याशित परिस्थितियों का सामना कर सकते हैं जिन्हें आपने नहीं माना था। दूसरे शब्दों में, आप सोच सकते हैं कि आपका नया कॉम्पैक्ट समाधान समतुल्य है, लेकिन यह सभी मामलों में नहीं है। जब तक कोड को अन्यथा करने के लिए एक सम्मोहक कारण नहीं है (प्रदर्शन, मेमोरी की कमी और इसी तरह), स्पष्टता राजा है।
रोब क्रेग

यह इस बात पर निर्भर करता है कि सूत्र क्या है। 'स्पष्ट से बेहतर है निहितार्थ देखें', यह हो सकता है कि 'छँटाई पहले' दृष्टिकोण अधिक स्पष्ट रूप से व्यक्त करता है कि कार्यक्रम क्या कर रहा है, या दूसरों में से एक। मुझे नहीं लगता कि हम सवाल से न्याय कर सकते हैं।
थॉमस अहले

101

एक के लिए तीन समानताएँ हल करना:

a in (b+c, b-c, c-b)

4
इसके साथ एकमात्र समस्या साइड इफेक्ट्स की है। यदि b या c अधिक जटिल अभिव्यक्ति हैं, तो उन्हें कई बार चलाया जाएगा।
सिल्वियो मेयोलो

3
@Kroltan मेरी बात यह थी कि मैंने वास्तव में उनके प्रश्न का उत्तर दिया, जिसने "अधिक कॉम्पैक्ट" प्रतिनिधित्व के लिए कहा। देखें: en.m.wikipedia.org/wiki/Short-circuit_evaluation
एलेक्स वर्गा

24
इस कोड को पढ़ने वाला कोई भी व्यक्ति आपको "चतुर" होने के लिए शाप देगा।
Karoly Horvath

5
@SilvioMayolo एक ही मूल का सच है
इज़काता

1
@AlexVarga, "मेरा कहना था कि मैंने वास्तव में उनके प्रश्न का उत्तर दिया था"। तुमने किया; यह 30% कम वर्ण (ऑपरेटरों के बीच रिक्त स्थान डाल) का उपयोग करता है। मैं यह कहने की कोशिश नहीं कर रहा था कि आपका उत्तर गलत था, केवल इस बात पर टिप्पणी करना कि यह कैसा मुहावरा है। अच्छा उत्तर।
पॉल ड्रेपर

54

पायथन में एक anyफ़ंक्शन होता है जो orएक अनुक्रम के सभी तत्वों पर करता है। यहाँ मैंने आपके कथन को 3-तत्व टपल में बदल दिया है।

any((a + b == c, a + c == b, b + c == a))

ध्यान दें कि orकम सर्कुलेटिंग है, इसलिए यदि व्यक्तिगत स्थितियों की गणना करना महंगा है, तो अपने मूल निर्माण को रखना बेहतर हो सकता है।


2
any()और all()शॉर्ट-सर्किट भी।
TigerhawkT3

42
@ TigerhawkT3 हालांकि इस मामले में नहीं; टपल के अस्तित्व में आने से पहले तीनों भावों का मूल्यांकन किया जाएगा, और रस्सा anyभी चलने से पहले मौजूद होगा ।
प्रहार

13
ओह समझा। मुझे लगता है कि यह केवल तभी है जब वहां जनरेटर या समान आलसी इटरेटर हो।
TigerhawkT3

4
anyऔर all"शॉर्ट-सर्किट" जो वे दिए गए हैं, उसकी जांच करने की प्रक्रिया ; लेकिन अगर यह एक जनरेटर के बजाय चलने योग्य है, तो फ़ंक्शन कॉल होने से पहले ही इसका पूरी तरह से मूल्यांकन किया जा चुका है
कार्ल स्नेचटेल

इसका यह फायदा है कि यह कई लाइनों (डबल-इंडेंट दलील टू द any, सिंगल-इंडेंट ):इन द ifस्टेटमेंट) को विभाजित करने में आसान है , जो कि गणित में शामिल होने पर पठनीयता के लिए बहुत मदद करता है
इज़्काता

40

यदि आप जानते हैं कि आप केवल सकारात्मक संख्या के साथ काम कर रहे हैं, तो यह काम करेगा, और बहुत साफ है:

a, b, c = sorted((a, b, c))
if a + b == c:
    do_stuff()

जैसा कि मैंने कहा, यह केवल सकारात्मक संख्याओं के लिए काम करता है; लेकिन अगर आप जानते हैं कि वे सकारात्मक होने जा रहे हैं, तो यह एक बहुत ही पठनीय समाधान IMO है, यहां तक ​​कि सीधे फ़ंक्शन में विरोध के रूप में कोड में भी।

आप ऐसा कर सकते हैं, जो बार-बार गणना करने का एक तरीका हो सकता है; लेकिन आपने प्रदर्शन को अपने लक्ष्य के रूप में निर्दिष्ट नहीं किया:

from itertools import permutations

if any(x + y == z for x, y, z in permutations((a, b, c), 3)):
    do_stuff()

या बिना permutations()और बार-बार गणना की संभावना:

if any(x + y == z for x, y, z in [(a, b, c), (a, c, b), (b, c, a)]:
    do_stuff()

मैं शायद इसे, या किसी अन्य समाधान को एक समारोह में रखूंगा। फिर आप अपने कोड में फ़ंक्शन को केवल सफाई से कॉल कर सकते हैं।

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

def two_add_to_third(a, b, c):
    return a + b == c or a + c == b or b + c == a

if two_add_to_third(a, b, c):
    do_stuff()

यह बहुत पाइथोनिक है, और यह संभवतः इसे करने का सबसे कुशल तरीका है (अतिरिक्त फ़ंक्शन कॉल एक तरफ); हालांकि आपको किसी भी तरह से प्रदर्शन के बारे में बहुत अधिक चिंता नहीं करनी चाहिए, जब तक कि यह वास्तव में एक मुद्दा नहीं है।


खासकर अगर हम मान सकते हैं कि बी, सी सभी गैर-नकारात्मक हैं।
cphlewis

मुझे लगता है कि वाक्यांश "हमेशा काम नहीं करता" थोड़ा भ्रमित करता है। पहला समाधान केवल तभी काम करता है जब आपको पता हो कि आपके नंबर गैर-नकारात्मक हैं। उदाहरण के लिए (ए, बी, सी) = (-3, -2, -1) के साथ आपके पास एक + बी! = सी लेकिन बी + सी = ए है। इसी तरह के मामलों (-1, 1, 2) और (-2, -1, 1) के साथ।
यूजरनंबर

@usernumber, आप जानते हैं, मैंने देखा है कि पहले; मुझे यकीन नहीं है कि मैंने इसे ठीक क्यों नहीं किया।
साइशेफ

आपका शीर्ष समाधान इनपुट के एक बड़े वर्ग के लिए काम नहीं करता है, जबकि ओपी का सुझाव सभी इनपुट के लिए काम करता है। "काम" की तुलना में "पायथोनिक" अधिक काम कैसे नहीं कर रहा है?
बैरी

3
ऊह, तस्वीर। " यदि आप जानते हैं कि आप केवल सकारात्मक संख्या के साथ काम कर रहे हैं , तो यह काम करेगा, और बहुत साफ है"। अन्य सभी किसी भी संख्या के लिए काम करते हैं, लेकिन अगर आप जानते हैं कि आप केवल सकारात्मक संख्याओं के साथ काम कर रहे हैं , तो शीर्ष एक बहुत पठनीय / पायथोनिक आईएमओ है।
साइफेज

17

यदि आप केवल तीन चर का उपयोग कर रहे हैं तो आपकी प्रारंभिक विधि:

a + b == c or a + c == b or b + c == a

पहले से ही बहुत अजगर है।

यदि आप अधिक चर का उपयोग करने की योजना बनाते हैं तो आपके तर्क करने की विधि:

a + b + c in (2*a, 2*b, 2*c)

बहुत होशियार है लेकिन सोचने देता है कि क्यों। यह काम क्यों करता है?
अच्छी तरह से कुछ सरल अंकगणित के माध्यम से हम देखते हैं कि:

a + b = c
c = c
a + b + c == c + c == 2*c
a + b + c == 2*c

और यह या तो क, ख, ग या के लिए सच धारण करने के लिए है, जिसका अर्थ है कि हाँ यह बराबर होगा होगा 2*a, 2*b, या 2*c। यह किसी भी प्रकार के चर के लिए सही होगा।

तो इसे जल्दी से लिखने का एक अच्छा तरीका बस आपके चर की एक सूची होगी और दोगुने मूल्यों की सूची के खिलाफ उनकी राशि की जांच करना होगा।

values = [a,b,c,d,e,...]
any(sum(values) in [2*x for x in values])

इस तरह, आपके द्वारा किए जाने वाले समीकरण में और अधिक चर जोड़ने के लिए, अपनी मान सूची को 'n' नए चर द्वारा संपादित करें, न कि 'n' समीकरण लिखें।


4
क्या a=-1, के बारे में b=-1, c=-2तब a+b=c, लेकिन है a+b+c = -4और 2*max(a,b,c)है-2
एरिक रेनॉफ

धन्यवाद कि यह सच है, मुझे एब्स का उपयोग करने की आवश्यकता होगी। अब वह समायोजन कर रहा है।
ThatGuyRussell

2
आधा दर्जन abs()कॉल के साथ इसे लागू करने के बाद , यह ओपी के स्निपेट की तुलना में पाइथोनिक है (मैं वास्तव में इसे काफी कम रीडिंग कहूंगा)।
TigerhawkT3

यह बहुत सही है, मैं इसे अभी समायोजित कर
दूंगा

1
@ThatGuyRussell शॉर्ट सर्किट के क्रम में, आप एक जनरेटर का उपयोग करना चाहते हैं ... कुछ इस तरह any(sum(values) == 2*x for x in values), कि आपको आगे के सभी दोहरीकरण करने की ज़रूरत नहीं होगी, बस आवश्यकतानुसार।
बैरी

12

निम्नलिखित कोड का उपयोग प्रत्येक तत्व को दूसरों के योग के साथ तुलना करने के लिए किया जा सकता है, जो उस तत्व को छोड़कर पूरी सूची के योग से गणना की जाती है।

 l = [a,b,c]
 any(sum(l)-e == e for e in l)

2
अच्छा :) मुझे लगता है कि अगर आप []कोष्ठक को दूसरी पंक्ति से हटाते हैं , तो यह शॉर्ट सर्किट भी करेगा जैसे मूल के साथ or...
psmears

1
जो मूल रूप से any(a + b + c == 2*x for x in [a, b, c]), ओपी के सुझाव के काफी करीब है
njzk2

यह समान है, हालांकि यह विधि किसी भी प्रकार के चर तक फैली हुई है। मैंने लघु-परिच्छेद के बारे में @psmears द्वारा सुझाव को शामिल किया।
अर्चनाम

10

कोशिश मत करो और इसे सरल करो। इसके बजाय, एक फ़ंक्शन के साथ आप क्या कर रहे हैं नाम :

def any_two_sum_to_third(a, b, c):
  return a + b == c or a + c == b or b + c == a

if any_two_sum_to_third(foo, bar, baz):
  ...

स्थिति को कुछ "चतुर" के साथ बदलें इससे यह कम हो सकता है, लेकिन यह इसे और अधिक पठनीय नहीं बनाएगा। इसे छोड़कर, यह कैसे भी बहुत पठनीय नहीं है, क्योंकि यह जानना मुश्किल है कि आप एक नज़र में उन तीन स्थितियों की जाँच क्यों कर रहे हैं। इससे यह बिल्कुल स्पष्ट हो जाता है कि आप क्या जाँच रहे हैं।

प्रदर्शन के बारे में, यह दृष्टिकोण एक फ़ंक्शन कॉल के ओवरहेड को जोड़ता है, लेकिन प्रदर्शन के लिए पठनीयता का कभी भी त्याग नहीं करता है जब तक कि आपको एक अड़चन नहीं मिली है जो आपको बिल्कुल ठीक करना चाहिए। और हमेशा मापते हैं, क्योंकि कुछ चतुर कार्यान्वयन कुछ परिस्थितियों में कुछ फ़ंक्शन कॉल को दूर करने और इनलाइन करने में सक्षम हैं।


1
फ़ंक्शंस केवल तभी लिखे जाने चाहिए जब आप एक से अधिक स्पॉट में एक ही कोड का उपयोग करने की उम्मीद करते हैं या यदि कोड जटिल है। मूल प्रश्न में कोड के पुन: उपयोग का कोई उल्लेख नहीं है, और कोड की एक पंक्ति के लिए एक फ़ंक्शन लिखना न केवल ओवरकिल है, बल्कि यह वास्तव में पठनीयता को लागू करता है।
इगोर लेविकी

5
एफपी स्कूल ऑफ थिंग्स से आने वाले, मुझे बहुत असहमत होना पड़ता है और बताता है कि अच्छी तरह से नामित एक-लाइन फ़ंक्शन पठनीयता बढ़ाने के लिए सबसे अच्छे उपकरण हैं जो आप कभी भी पाएंगे। जब भी आप कुछ करने के लिए कदम उठा रहे हों, तब एक फंक्शन करें , जो आप कर रहे हैं, उसमें तुरंत स्पष्टता न लाएं , क्योंकि फ़ंक्शन का नाम आपको किसी भी टिप्पणी से बेहतर क्या बता सकता है।
जैक

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

9

अजगर 3:

(a+b+c)/2 in (a,b,c)
(a+b+c+d)/2 in (a,b,c,d)
...

यह किसी भी प्रकार के चर को मापता है:

arr = [a,b,c,d,...]
sum(arr)/2 in arr

हालांकि, सामान्य तौर पर मैं मानता हूं कि जब तक आपके पास तीन से अधिक चर नहीं हैं, मूल संस्करण अधिक पठनीय है।


3
फ़्लोटिंग पॉइंट राउंडिंग त्रुटियों के कारण कुछ इनपुट के लिए यह गलत परिणाम देता है।
पीटीएस

प्रदर्शन और सटीकता कारणों से विभाजन से बचा जाना चाहिए।
इगोर लेविक

1
@ Will फ्लोटिंग पॉइंट राउंडिंग के कारण क्या कोई कार्यान्वयन गलत परिणाम नहीं लौटाएगा? यहां तक ​​कि a + b == c
osundblad

@osundblad: यदि a, b और c ints हैं, तो (a + b + c) / 2 राउंडिंग करता है (और गलत परिणाम लौटा सकता है), लेकिन a + b == c सटीक है।
अंक

3
विभाजन 2 से बस घातांक को एक से कम कर रहा है, इसलिए यह किसी भी पूर्णांक के लिए सटीक होगा जो 2 ^ 53 (अजगर में एक फ्लोट का अंश) से कम है, और बड़े पूर्णांकों के लिए आप दशमलव का उपयोग कर सकते हैं । उदाहरण के लिए, पूर्णांक की जांच करने के लिए जो 2 ^ 30 से कम हैं[x for x in range(pow(2,30)) if x != ((x * 2)/ pow(2,1))]
विटाली फेडोरेंको

6
(a+b-c)*(a+c-b)*(b+c-a) == 0

यदि किसी भी दो शब्दों का योग तीसरे शब्द के बराबर है, तो कारकों में से एक शून्य होगा, जिससे संपूर्ण उत्पाद शून्य हो जाएगा।


मैं बिल्कुल वैसा ही सोच रहा था लेकिन मैं इस बात से इनकार नहीं कर सकता कि उसका मूल प्रस्ताव रास्ता साफ करने वाला है ...
user541686

@ मेहरदाद - निश्चित रूप से। यह वास्तव में से अलग नहीं है(a+b<>c) && (a+c<>b) && (b+c<>a) == false
mbckish

यह सिर्फ इतना है कि गुणा तार्किक भावों और बुनियादी अंकगणित की तुलना में अधिक महंगा है।
इगोर लेविकी

@IgorLevicki - हाँ, हालांकि यह एक बहुत समय से पहले अनुकूलन चिंता है। क्या यह प्रति सेकंड हजारों बार प्रदर्शन किया जा रहा है? यदि हाँ, तो आप शायद कुछ और देखना चाहते हैं।
मबेकिश

@mbeckish - आपको क्यों लगता है कि यह समय से पहले है? कोड को मन में अनुकूलन के साथ लिखा जाना चाहिए, एक विचार के बाद अनुकूलित नहीं। एक दिन कुछ इंटर्न इस कोड स्निपेट को कॉपी करेंगे और एक एम्बेडेड प्लेटफॉर्म पर कुछ परफॉर्मेंस क्रिटिकल लूप में पेस्ट करेंगे, जो बाद में लाखों डिवाइस पर चलेगा जो जरूरी नहीं कि वह जो भी करता है उसके लिए धीमा हो, लेकिन शायद अधिक बैटरी पावर बर्बाद कर रहा हो। इस तरह के कोड को लिखना केवल खराब कोडिंग प्रथाओं को प्रोत्साहित करता है। मेरी राय में, ओपी को क्या पूछना चाहिए था कि क्या उस तर्क अभिव्यक्ति को अनुकूलित करने का कोई तरीका है।
इगोर लेविक

6

कैसे बस के बारे में:

a == b + c or abs(a) == abs(b - c)

ध्यान दें कि यदि चर अप्रकाशित हैं तो यह काम नहीं करेगा।

कोड ऑप्टिमाइज़ेशन के दृष्टिकोण से (कम से कम x86 प्लेटफ़ॉर्म पर) यह सबसे कुशल समाधान लगता है।

आधुनिक संकलक दोनों एब्स () फ़ंक्शन कॉल को इनलाइन करेंगे और सीडीक्यू, एक्सओआर और एसयूबी निर्देशों के एक चतुर अनुक्रम का उपयोग करके साइन टेस्टिंग और बाद में सशर्त शाखा से बचेंगे । उपरोक्त उच्च-स्तरीय कोड इस प्रकार केवल निम्न-विलंबता, उच्च-थ्रूपुट ALU निर्देशों और सिर्फ दो स्थितियों के साथ दर्शाया जाएगा।


और मुझे लगता है कि fabs()इसका उपयोग floatप्रकारों के लिए किया जा सकता है ;)।
sha.t

4

एलेक्स वर्गा द्वारा प्रदान किया गया समाधान "ए (बी + सी, बीसी, सीबी)" कॉम्पैक्ट और गणितीय रूप से सुंदर है, लेकिन मैं वास्तव में इस तरह से कोड नहीं लिखूंगा क्योंकि साथ आने वाले अगले डेवलपर तुरंत कोड के उद्देश्य को नहीं समझ पाएंगे। ।

मार्क रैंसम के समाधान

any((a + b == c, a + c == b, b + c == a))

अधिक स्पष्ट है, लेकिन बहुत अधिक रसीला नहीं है

a + b == c or a + c == b or b + c == a

जब कोड लिखते हैं कि किसी और को देखना होगा, या कि मुझे लंबे समय बाद देखना होगा जब मैं भूल गया हूं कि मैं क्या सोच रहा था जब मैंने इसे लिखा था, बहुत छोटा या चालाक होना अच्छा से अधिक नुकसान करने के लिए जाता है। कोड पठनीय होना चाहिए। इसलिए सक्सेसफुल अच्छा है, लेकिन इतना सक्सेन्केट नहीं कि अगला प्रोग्रामर इसे समझ न सके।


ईमानदार सवाल: लोग हमेशा यह क्यों मानते हैं कि अगला प्रोग्रामर रीडिंग कोड के लिए एक मूर्ख होगा? मुझे व्यक्तिगत रूप से वह विचार अपमानजनक लगता है। यदि कोड को प्रत्येक प्रोग्रामर के लिए स्पष्ट रूप से स्पष्ट होना लिखा जाना चाहिए, तो इसका मतलब है कि हम एक पेशे के रूप में सबसे आम हर के लिए खानपान कर रहे हैं, हमारे बीच कम से कम कुशल है। अगर हम ऐसा करते रहेंगे, तो वे अपने व्यक्तिगत कौशल को कैसे सुधारेंगे? मैं इसे अन्य व्यवसायों में नहीं देखता। जब आखिरी बार आपने एक संगीतकार को एक साधारण संगीत स्कोर लिखते देखा था ताकि हर संगीतकार कौशल स्तर की परवाह किए बिना इसे खेल सके?
इगोर लेविक

6
मुद्दा यह है कि यहां तक ​​कि प्रोग्रामर के पास सीमित मानसिक ऊर्जा है, इसलिए क्या आप एल्गोरिथम और प्रोग्राम के उच्च स्तर के पहलुओं पर अपनी सीमित मानसिक ऊर्जा खर्च करना चाहते हैं, या यह पता लगाने पर कि कोड की कुछ जटिल रेखा का क्या मतलब है जब इसे और अधिक आसानी से व्यक्त किया जा सकता है ? प्रोग्रामिंग कठिन है, इसलिए इसे अनावश्यक रूप से अपने आप पर कठिन मत बनाओ, जैसे कि एक ओलंपिक धावक सिर्फ इसलिए कि वे कर सकते हैं पर एक भारी बैग के साथ दौड़ नहीं होगी। जैसा कि स्टीव मैककोनेल कोड पूरा 2 में कहते हैं, पठनीयता कोड के सबसे महत्वपूर्ण पहलुओं में से एक है।
पॉल जे अबरनेथी

2

अनुरोध अधिक कॉम्पैक्ट या अधिक पायथोनिक के लिए है - मैंने अपने हाथ को और अधिक कॉम्पैक्ट करने की कोशिश की।

दिया हुआ

import functools, itertools
f = functools.partial(itertools.permutations, r = 3)
def g(x,y,z):
    return x + y == z

यह मूल से 2 वर्ण कम है

any(g(*args) for args in f((a,b,c)))

के साथ परीक्षण:

assert any(g(*args) for args in f((a,b,c))) == (a + b == c or a + c == b or b + c == a)

इसके अतिरिक्त, दिया गया:

h = functools.partial(itertools.starmap, g)

यह बराबर है

any(h(f((a,b,c))))

खैर, यह दो पात्रों की तुलना में कम है, लेकिन ओपी ने सही बाद में नहीं दिया, जो उसने कहा कि वह वर्तमान में उपयोग कर रहा है। मूल में बहुत सारे व्हाट्सएप भी शामिल हैं, जो कि जब भी संभव होता है, छोड़ देता है। कार्य g()करने के लिए आपको जिस फ़ंक्शन को परिभाषित करना है, उसका भी छोटा मामला है । यह सब देखते हुए, मैं कहूंगा कि यह काफी बड़ा है।
TigerhawkT3

@ TigerhawkT3, मैंने इसे एक छोटी अभिव्यक्ति / लाइन के लिए अनुरोध के रूप में व्याख्या की। आगे सुधार के लिए संपादित देखें ।
wwii

4
बहुत खराब फ़ंक्शन नाम, केवल एक कोड गोल्फ के लिए उपयुक्त है।
0xc0de

@ 0xc0de - माफ करना, मैं नहीं खेलता। उपयुक्त व्यक्तिपरक और परिस्थितियों पर निर्भर हो सकता है - लेकिन मैं समुदाय के लिए स्थगित कर दूंगा।
wwii

मैं यह नहीं देखता कि मूल कोड की तुलना में अधिक वर्ण होने पर यह अधिक कॉम्पैक्ट कैसे है।
इगोर लेविकी

1

मैं पेश करना चाहता हूं कि मैं सबसे अधिक पायथनिक उत्तर के रूप में क्या देखता हूं :

def one_number_is_the_sum_of_the_others(a, b, c):
    return any((a == b + c, b == a + c, c == a + b))

सामान्य मामला, गैर-अनुकूलित:

def one_number_is_the_sum_of_the_others(numbers):
    for idx in range(len(numbers)):
        remaining_numbers = numbers[:]
        sum_candidate = remaining_numbers.pop(idx)
        if sum_candidate == sum(remaining_numbers):
            return True
    return False 

पायथन के ज़ेन के संदर्भ में मुझे लगता है कि अन्य उत्तरों की तुलना में जोर दिए गए बयानों का अधिक पालन किया जाता है:

टिम पीटर्स द्वारा ज़ेन ऑफ़ पायथन

सुंदर बदसूरत से बेहतर है।
निहितार्थ की तुलना में स्पष्ट है।
सरल जटिल से बेहतर है।
कॉम्प्लेक्स जटिल से बेहतर है।
फ्लैट नेस्टेड से बेहतर है।
विरल घने से बेहतर है।
पठनीयता मायने रखती है।
नियम तोड़ने के लिए विशेष मामले पर्याप्त नहीं हैं।
यद्यपि व्यावहारिकता शुद्धता को हरा देती है।
त्रुटियों को कभी भी चुपचाप नहीं गुजरना चाहिए।
जब तक स्पष्ट रूप से चुप नहीं कराया जाता।
अस्पष्टता के सामने, अनुमान लगाने के प्रलोभन से इनकार करें।
वहाँ एक होना चाहिए - और अधिमानतः इसे करने के लिए केवल एक ही - स्पष्ट तरीका।
हालाँकि यह तरीका पहली बार में स्पष्ट नहीं हो सकता जब तक कि आप डच न हों।
अब पहले से बेहतर है।
हालांकि कभी-कभी इससे बेहतर नहीं होता हैसही अब।
यदि कार्यान्वयन को समझाना कठिन है, तो यह एक बुरा विचार है।
यदि कार्यान्वयन की व्याख्या करना आसान है, तो यह एक अच्छा विचार हो सकता है।
नाम स्थान एक महान विचार का सम्मान कर रहे हैं - चलो उन में से अधिक करते हैं!


1

मेरी प्रोग्रामिंग की एक पुरानी आदत के रूप में, मुझे लगता है कि एक क्लॉज में दाईं ओर जटिल अभिव्यक्ति रखने से इसे इस तरह अधिक पठनीय बनाया जा सकता है:

a == b+c or b == a+c or c == a+b

प्लस ():

((a == b+c) or (b == a+c) or (c == a+b))

और मुझे भी लगता है कि मल्टी-लाइनों का उपयोग करके इस तरह से अधिक इंद्रियां बनाई जा सकती हैं:

((a == b+c) or 
 (b == a+c) or 
 (c == a+b))

0

एक सामान्य तरीके से,

m = a+b-c;
if (m == 0 || m == 2*a || m == 2*b) do_stuff ();

यदि, इनपुट चर में हेरफेर करना आपके लिए ठीक है,

c = a+b-c;
if (c==0 || c == 2*a || c == 2*b) do_stuff ();

अगर आप बिट हैक्स का उपयोग करके शोषण करना चाहते हैं, तो आप "!", ">> 1" और "<< 1" का उपयोग कर सकते हैं

मैंने विभाजन को टाल दिया हालांकि यह राउंड ऑफ एरर से बचने के लिए दो गुणा से बचने के लिए उपयोग को सक्षम बनाता है। हालांकि, ओवरफ्लो की जांच करें


0
def any_sum_of_others (*nums):
    num_elements = len(nums)
    for i in range(num_elements):
        discriminating_map = map(lambda j: -1 if j == i else 1, range(num_elements))
        if sum(n * u for n, u in zip(nums, discriminating_map)) == 0:
            return True
    return False

print(any_sum_of_others(0, 0, 0)) # True
print(any_sum_of_others(1, 2, 3)) # True
print(any_sum_of_others(7, 12, 5)) # True
print(any_sum_of_others(4, 2, 2)) # True
print(any_sum_of_others(1, -1, 0)) # True
print(any_sum_of_others(9, 8, -4)) # False
print(any_sum_of_others(4, 3, 2)) # False
print(any_sum_of_others(1, 1, 1, 1, 4)) # True
print(any_sum_of_others(0)) # True
print(any_sum_of_others(1)) # False

फ़ंक्शंस केवल तभी लिखे जाने चाहिए जब आप एक से अधिक स्पॉट में एक ही कोड का उपयोग करने की उम्मीद करते हैं या यदि कोड जटिल है। मूल प्रश्न में कोड के पुन: उपयोग का कोई उल्लेख नहीं है, और कोड की एक पंक्ति के लिए एक फ़ंक्शन लिखना न केवल ओवरकिल है, बल्कि यह वास्तव में पठनीयता को लागू करता है।
इगोर लेविकी

मैं असहमत हूं कि यह पठनीयता को बाधित करता है; यदि आप एक उपयुक्त नाम चुनते हैं तो यह पठनीयता में सुधार कर सकता है (लेकिन मैं इस उत्तर में चुने गए नाम की गुणवत्ता के अनुसार कोई प्रतिनिधित्व नहीं करता हूं)। इसके अलावा, यह एक अवधारणा को एक नाम देने के लिए सहायक हो सकता है, जो आपको तब तक करना होगा जब तक आप अपने कार्य को एक अच्छा नाम देने के लिए खुद को मजबूर न करें। कार्य अच्छे हैं। जैसे कि कार्यक्षमता किसी कार्य में संलग्न होने से लाभ के लिए पर्याप्त जटिल है, यह एक व्यक्तिपरक निर्णय है।
Hammerite
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.