क्या अजगर लिखने के लिए नेस्टेड लिखने का एक बेहतर तरीका है? [बन्द है]


34

वहाँ एक और pythonic तरीका है नेस्टेड करने के लिए अगर इस एक से अधिक बयान:

def convert_what(numeral_sys_1, numeral_sys_2):

    if numeral_sys_1 == numeral_sys_2:      
        return 0
    elif numeral_sys_1 == "Hexadecimal":
        if numeral_sys_2 == "Decimal":
            return 1
        elif numeral_sys_2 == "Binary":
            return 2
    elif numeral_sys_1 == "Decimal":
        if numeral_sys_2 == "Hexadecimal":
            return 4
        elif numeral_sys_2 == "Binary":
            return 6
    elif numeral_sys_1 == "Binary":
        if numeral_sys_2 == "Hexadecimal":
            return 5
        elif numeral_sys_2 == "Decimal":
            return 3
    else:
        return 0

यह स्क्रिप्ट एक साधारण कनवर्टर का एक हिस्सा है।


किसी अन्य डेटा संरचना का उपयोग किए बिना, आप नेस्टेड-और स्टेटमेंट को andशीर्ष स्तर के लिए शर्तों में स्टेटमेंट दे सकते हैं यदि-इतर स्टेटमेंट्स। यह कम से कम उस तरह से अधिक पठनीय होगा। अफसोस की बात है कि अजगर के पास स्विच स्टेटमेंट नहीं हैं।
adamkgray

यह है pythonic तरीका है। पायथन जानबूझकर स्विच स्टेटमेंट का समर्थन नहीं करता है। Python.org/dev/peps/pep-3103
जोंगमिन बाके

1
इस सवाल पर बिल्कुल नहीं, लेकिन अगर आप चीजों को अधिक पाइथोनिक बनाने की कोशिश कर रहे हैं, तो कैसे स्थिरांक को परिभाषित करने या वापसी मूल्यों के लिए एक पहेली के बारे में - "जादू संख्या" की तुलना में एक पाठक के लिए अच्छे हैं ....
मैट विचमन

जवाबों:


13

जबकि @Aryerez और @ SencerH के उत्तर काम करते हैं, प्रत्येक संभावित मान के numeral_sys_1बार-बार लिखे जाने पर प्रत्येक संभावित मान के लिए लिखा जाता है numeral_sys_2जब मूल्य युग्मों की सूची बनाते हैं, तो डेटा संरचना को बनाए रखना कठिन होता है जब संभव मानों की संख्या बढ़ जाती है। यदि आप इसके बजाय अपने नेस्टेड के स्थान पर नेस्टेड डिक्टेड का उपयोग कर सकते हैं:

mapping = {
    'Hexadecimal': {'Decimal': 1, 'Binary': 2},
    'Binary': {'Decimal': 3, 'Hexadecimal': 5},
    'Decimal': {'Hexadecimal': 4, 'Binary': 6}
}
def convert_what(numeral_sys_1, numeral_sys_2):
    return mapping.get(numeral_sys_1, {}).get(numeral_sys_2, 0)

वैकल्पिक रूप से, आप itertools.permutationsविधि के साथ मानचित्रण के लिए मानों के जोड़े उत्पन्न कर सकते हैं , जिनमें से क्रम इनपुट अनुक्रम का अनुसरण करता है:

mapping = dict(zip(permutations(('Hexadecimal', 'Decimal', 'Binary'), r=2), (1, 2, 4, 6, 3, 5)))
def convert_what(numeral_sys_1, numeral_sys_2):
    return mapping.get((numeral_sys_1, numeral_sys_2), 0)

29

एक करने के लिए सभी मान्य संयोजनों डालें dictionaryकी tupleहै, और अगर संयोजन वहाँ नहीं है, लौटने 0:

def convert_what(numeral_sys_1, numeral_sys_2):
    numeral_dict = {
        ("Hexadecimal", "Decimal"    ) : 1,
        ("Hexadecimal", "Binary"     ) : 2,
        ("Decimal",     "Hexadecimal") : 4, 
        ("Decimal",     "Binary"     ) : 6,
        ("Binary",      "Hexadecimal") : 5,
        ("Binary",      "Decimal"    ) : 3
    }
    return numeral_dict.get((numeral_sys_1, numeral_sys_2), 0)

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



@RomanPerekhrest मैंने इसे जोड़ा है, हालांकि इस विशिष्ट प्रश्न में, फ़ंक्शन के पास अन्य प्रकार की त्रुटि नहीं है जो कि अपने मूल फ़ंक्शन से एक अलग आउटपुट देगा।
आर्यसेर

1
परगनों के अंदर बेमानी हैं []। खाली टपल को छोड़कर, यह अल्पविराम है जो इसे टपल बनाता है, कोष्ठक नहीं, यह केवल कुछ मामलों में संचालन के आदेश के लिए है।
गिलाक

4
आप सिर्फ बयान के बजाय डिफ़ॉल्ट के .get()साथ तानाशाही विधि का उपयोग कर सकते हैं । 0try
गिलच

@ गिलच मैं कोष्ठक गिरा दिया। लेकिन मुझे try:... except:...संरचना पसंद है ।
आर्यसेर

17

यदि आप सुनिश्चित हैं कि कोई और मान numeral_sys_1 और numeral_sys_2 पर सेट नहीं किया जा सकता है तो यह सबसे सरल और सबसे साफ समाधान है।

दूसरी ओर, आपको शब्दकोश को उपलब्ध मूल्यों के साथ संयोजन के साथ विस्तारित करना होगा, यदि आपके पास "हेक्साडेसिमल", "दशमलव" और "बाइनरी" के अलावा कोई अन्य मूल्य है

यहाँ तर्क है; अगर शब्द कुंजियों में परिवर्तनीय ट्यूपल दिए गए वैरिएबल ट्यूपल के बराबर नहीं हैं, तो .get () विधि रिटर्न "0" है। यदि दिए गए वेरिएबल टपल को डिक्शनरी में किसी भी कुंजी से मेल खाते हैं, तो मिलान कुंजी का रिटर्न वैल्यू है।

def convert_what(numeral_sys_1, numeral_sys_2):
    return {
        ("Hexadecimal", "Decimal") : 1, 
        ("Hexadecimal", "Binary") : 2, 
        ("Binary", "Decimal") : 3,
        ("Decimal", "Hexadecimal") : 4,
        ("Binary", "Hexadecimal") : 5, 
        ("Decimal", "Binary") : 6, 
     }.get((numeral_sys_1, numeral_sys_2), 0)

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


अंतिम 'और: रिटर्न 0' की मेरी व्याख्या यह है कि तर्क मेल नहीं खाते हैं और सूची में उन लोगों के बगल में कुछ और हो सकता है (यानी आपकी तानाशाही कुंजी)।
tocode

@tocode हाँ, आप सही हैं। लेकिन यह विधि समान कार्यक्षमता भी प्रदान करती है। यदि विधि को दिए गए कोई या दोनों तर्क, कहते हैं, स्ट्रिंग नहीं, यहां तक ​​कि कोई भी प्रकार का मूल्य नहीं है; शब्दकोश में कुंजी की कमी के कारण .get () विधि वापसी "0"। क्या यह सरल नहीं है?
सेंसर एच।

क्या आपने अभी आर्येरेज़ के उत्तर की नकल नहीं की है?
मार्टिन

@ मेरा नहीं, मैंने नहीं किया। आप स्पष्ट रूप से इस बिंदु को याद कर रहे हैं। कुछ करने के कई तरीके हैं लेकिन सही तरीका सिखाना मैं यहाँ करने के लिए तैयार हूँ। वास्तव में नीचे बेहतर उत्तर है। फ़ुरकान्याद के समाधान पर एक नज़र डालें। यह त्रुटिपूर्ण है और इसमें इनाम मिलना है।
सेन्सर एच।

@ SencerH। केवल अंतर यह था कि आपने तानाशाही विधि का उपयोग किया () जो मूल रूप से मूल उत्तर की कोशिश / को छोड़कर है। आप इस तथ्य से इंकार नहीं कर सकते हैं, कि आपने विचार की नकल की है और बहुत कम (सुधार के बिना) संशोधित और प्रकाशित
मार्टिन

3

नेस्टेड सूची का उपयोग करके एक वैकल्पिक तरीका। आशा है ये मदद करेगा!!

def convert_what(numeral_sys_1, numeral_sys_2):

    l1 = [["Hexadecimal","Decimal"],["Hexadecimal","Binary"],
            ["Decimal","Hexadecimal"],["Decimal","Binary"],
            ["Binary","Hexadecimal"],["Binary","Decimal"]]

    return l1.index([numeral_sys_1, numeral_sys_2]) + 1 if [numeral_sys_1,numeral_sys_2] in l1 else 0

2

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

पहला कदम, हर संयोजन के लिए एक कार्य करें:

def hex_dec(inp):
    return 1234  # todo implement
# do the same for hex_bin, bin_dec, dec_hex, bin_hex, dec_bin

दूसरा चरण, फ़ंक्शन ऑब्जेक्ट्स को एक तानाशाही में रखें। ध्यान दें कि फ़ंक्शन नामों के बाद कोई () नहीं हैं, क्योंकि हम फ़ंक्शन ऑब्जेक्ट को संग्रहीत करना चाहते हैं और इसे अभी तक कॉल नहीं करते हैं:

converter_funcs = {
    ("Hexadecimal", "Decimal"): hex_dec,
    ("Hexadecimal", "Binary"): hex_bin,
    ("Binary", "Decimal"): bin_dec,
    ("Decimal", "Hexadecimal"): dec_hex,
    ("Binary", "Hexadecimal"): bin_hex,
    ("Decimal", "Binary"): dec_bin,
}

तीसरा और अंतिम चरण, एक कन्वर्ट फ़ंक्शन लागू करें। यदि स्टेटमेंट चेक करता है कि क्या दोनों सिस्टम समान हैं। फिर, हम अपने तानाशाही से सही कार्य प्राप्त करते हैं और इसे कहते हैं:

def convert(input_number, from_sys, to_sys):
    if from_sys == to_sys:
        return input_number
    func = converter_funcs[(from_sys, to_sys)]
    return func(input_number)

2

यह ज्यादातर अन्य भाषाओं में स्विच-केस स्टेटमेंट द्वारा किया जाता है। अजगर में, मैं एक अभिव्यक्ति शब्दकोश के साथ एक साधारण फ़ंक्शन का उपयोग करता हूं।

कोड:

def convert_what(numeral_sys_1, numeral_sys_2):
    myExpressions = {"Hexadecimal" : {"Decimal" : 1, "Binary" : 2},
                    "Decimal" : {"Hexadecimal" : 4, "Binary" : 6}, 
                    "Binary" : {"Hexadecimal" : 5, "Decimal" : 3}}
    return (myExpressions.get(numeral_sys_1, {})).get(numeral_sys_2, 0)

आउटपुट:

> convert_what("Hexadecimal", "Decimal")
> 1
> convert_what("Binary", "Binary")
> 0
> convert_what("Invalid", "Hexadecimal")
> 0

यह शीर्ष उत्तर के लिए एक अच्छा विकल्प है और अधिक मूल्यों में भी विस्तार करना आसान है।
गखनवरो

यह पिछले उत्तर के समान है: stackoverflow.com/a/58985114/1895261 । इसके अलावा, मुझे लगता है कि अंतिम पंक्ति को 0 के बजाए खाली डिफेंस को वापस करना चाहिए, जिसमें numeral_sys_1 बाहरी डिक्‍टर में नहीं है: return (myExpressions.get (numeral_sys_1, {}))। (Num.sys_2, 0)
Sepia

@ सवाल में Sepia Module_art 0 पर एक और कथन देता है, जिसका अर्थ है कि 0 कुछ भी दिए गए और समानता की स्थिति के अनुरूप नहीं है।
फुरकानायड

1
अपने कोड के साथ प्रिंट (Convert_what ("अमान्य", "Hexadecimal")) चलाने का प्रयास करें। यह एक त्रुटि पैदा करेगा: "गुण: 'int' ऑब्जेक्ट में कोई विशेषता नहीं है 'प्राप्त करें"। खाली 0 के साथ पहले 0 को प्रतिस्थापित करना ({}) फंक्शन को सही ढंग से कर देगा 0 0 मामले में numeral_sys_1 अमान्य है।
सेपिया

1

सामान्य तौर पर मैं नेस्टेड के लिए डिक्शनरी सॉल्यूशन के साथ चलूंगा अगर टास्क हो। कुछ विशेष मामले दूसरे दृष्टिकोण में ला सकते हैं। इस तरह:

def convert_what(numeral_sys_1, numeral_sys_2):

    num = ['Hexadecimal','Decimal','Binary']
    tbl = [[0,1,2],
           [4,0,6],
           [5,3,0]]
    try:
        return tbl[num.index(numeral_sys_1)][num.index(numeral_sys_2)]
    except ValueError:
        return 0

1

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

def convert_what(numeral_sys_1, numeral_sys_2):
    src = numeral_sys_1, numeral_sys_2
    if src == "Hexadecimal", "Decimal":
        return 1
    if src == "Hexadecimal", "Binary"
        return 2
    # You get the gist.... 
    if src == "Decimal", "Binary":
        return 6
    return 0 

1

एक आइडिया एक सूची का उपयोग कर रहा है और परिणाम का सूचकांक प्राप्त करता है, अर्थात।

def convert_what(numeral_sys_1, numeral_sys_2):
    if numeral_sys_1 == numeral_sys_2:      
        return 0
    return ["HexadecimalDecimal", "HexadecimalBinary", "BinaryDecimal", "DecimalHexadecimal", "BinaryHexadecimal", "DecimalBinary" ].index(numeral_sys_1 + numeral_sys_2) + 1

दिलचस्प सुझाव लेकिन यह तब काम नहीं करता जब तर्क होते हैं ("दशमलव", "नहीं"), जिसके परिणामस्वरूप ValueError: 'DecimalNot' सूची में नहीं है
अंकित करें

1

जैसा @ सडाप ने कहा,

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

यदि आप पूर्णांकों के लिए आधार रूपांतरण लागू कर रहे हैं, तो आप शायद वैसे भी एक सामान्य प्रतिनिधित्व से गुजर रहे हैं int:। प्रत्येक जोड़ी के लिए एक अलग फ़ंक्शन आवश्यक नहीं है, और इसमें शामिल दो आधारों को एक दूसरे के बारे में जानने की भी आवश्यकता नहीं है।

इनपुट

किसी संख्या प्रणाली के नाम से उसके आधार तक मानचित्रण बनाएँ:

BINARY = "Binary"
DECIMAL = "Decimal"
HEXADECIMAL = "Hexadecimal"

BASES = {
    BINARY: 2,
    DECIMAL: 10,
    HEXADECIMAL: 16,
}

आप के साथ आदानों को पढ़ने के लिए अनुमति देता है int(text, BASES[numeral_sys_1])

उत्पादन

एक प्रारूप प्रणाली के लिए एक नंबर प्रणाली के नाम से एक मानचित्रण बनाएँ :

FORMATTERS = {
    BINARY: "b",
    DECIMAL: "d",
    HEXADECIMAL: "x",
}

आपको आउटपुट लिखने की अनुमति देता है format(n, FORMATTERS[numeral_sys_2])

उदाहरण का उपयोग करें

def convert(text, numeral_sys_1, numeral_sys_2):
    n = int(text, BASES[numeral_sys_1])
    return format(n, FORMATTERS[numeral_sys_2])

या तो हुकुम को मानों को कार्य करने के बजाय अधिक सामान्य भी बनाया जा सकता है, यदि आपको प्रारूपों के एक अलग सेट का समर्थन करने की आवश्यकता है int(x, base), या निर्मित पूर्णांक स्वरूपण समर्थन की तुलना में अधिक आउटपुट आधार है।


0

मुझे कोड को सूखा रखना पसंद है:

def convert_what_2(numeral_sys_1, numeral_sys_2):
    num_sys = ["Hexadecimal", "Decimal", "Binary"]
    r_value = {0: {1: 1, 2: 2},
               1: {0: 4, 2: 6},
               2: {0: 5, 1: 3} }
    try:
        value = r_value[num_sys.index(numeral_sys_1)][num_sys.index(numeral_sys_2)]
    except KeyError: # Catches when they are equal or undefined
        value = 0
    return value

0

कुछ तकनीकों का उपयोग करना जो अन्य उत्तर प्रदान करते हैं और उन्हें संयोजित करते हैं:

def convert(key1, key2):
    keys = ["Hexadecimal", "Decimal", "Binary"]
    combinations = {(0, 1): 1, (0, 2): 2, (1, 0): 4, (1, 2): 6, (2, 0): 5, (2, 1): 3} # use keys indexes to map to combinations
    try:
        return combinations[(keys.index(key1), keys.index(key2))]
    except (KeyError, ValueError): # if value is not in list, return as 0
        return 0

-1

हालांकि यह सुनिश्चित नहीं है कि यह दृष्टिकोण तेज़ है, लेकिन साथ ही साथ इसे खस्ता का उपयोग करके भी किया जा सकता है:

conditions = [
    ("Hexadecimal", "Decimal"), ("Hexadecimal", "Binary"),
    ("Binary", "Decimal"), ("Decimal", "Hexadecimal"), ("Binary", "Hexadecimal"), ("Decimal", "Binary")]
choices = [1,2,3,4,5,6]

और इस रूप में इस्तेमाल किया जा सकता है:

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