Skip to content
This page has been auto-translated and may contain errors.View in English

लैम्ब्डा और कॉम्प्रिहेंशन

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

लैम्ब्डा, कॉम्प्रिहेंशन, और zip तीन ऐसे टूल्स हैं जो आम पैटर्न को एक्सप्रेशन में संक्षिप्त करते हैं। ये आवश्यक नहीं हैं, लेकिन Python कोड में हर जगह दिखाई देते हैं, और इन्हें पहचानना तथा धाराप्रवाह लिखना सीखने योग्य है। मार्गदर्शक सिद्धांत: इनका उपयोग तब करें जब ये इरादे को स्पष्ट बनाते हैं, केवल छोटा नहीं।

लैम्ब्डा एक्सप्रेशन रनटाइम पर अनाम फ़ंक्शन ऑब्जेक्ट्स बनाते हैं। कॉम्प्रिहेंशन ऑप्टिमाइज़्ड बाइटकोड में कंपाइल होते हैं जो बाहरी फ्रेम में for लूप के बिना कलेक्शन बनाते हैं। जनरेटर आलसी होते हैं: वे पूरे सीक्वेंस को मटीरियलाइज़ किए बिना मांग पर मान देते हैं। zip टपल्स का एक इटरेटर लौटाता है, इनपुट इटरेबल्स को आलसी ढंग से उपभोग करते हुए। तीनों परिवर्तनों को अनिवार्य लूप के बजाय एक्सप्रेशन के रूप में व्यक्त करने का विषय साझा करते हैं।

लैम्ब्डा फ़ंक्शन

लैम्ब्डा एक नामहीन, एक-एक्सप्रेशन वाला फ़ंक्शन है। आप इसे lambda कीवर्ड से बनाते हैं। इसकी असली उपयोगिता यह है कि आप इसे इनलाइन लिख सकते हैं, ठीक वहीं जहाँ आपको ज़रूरत हो, बिना पहले नामित फ़ंक्शन परिभाषित किए। यही बात इसे sorted() के साथ उपयोगी बनाती है।

लैम्ब्डा एक अनाम एकल-एक्सप्रेशन फ़ंक्शन है। यह कई आर्ग्युमेंट्स ले सकता है लेकिन इसका बॉडी एक एकल एक्सप्रेशन होना चाहिए, स्टेटमेंट नहीं। इसका प्राथमिक उपयोग इनलाइन key= या कॉलबैक आर्ग्युमेंट के रूप में होता है जहाँ पूर्ण def अनावश्यक मध्यस्थता जोड़ेगा। किसी भी अधिक जटिल चीज़ के लिए, def का उपयोग करें।

lambda args: expression एक कोड ऑब्जेक्ट में कंपाइल होता है और एक फ़ंक्शन ऑब्जेक्ट बनाता है, def के समान सिवाय इसके कि इसका कोई नाम नहीं होता (यह ट्रेसबैक में <lambda> के रूप में दिखाई देता है), स्टेटमेंट्स नहीं रख सकता, और docstring या एनोटेशन का समर्थन नहीं करता। लैम्ब्डा क्लोज़र में भाग लेते हैं: मुक्त वैरिएबल्स आस-पास के स्कोप से कैप्चर होते हैं। आम गलती: लूप में lambda i: i i को मान से नहीं, संदर्भ से कैप्चर करता है; निर्माण समय पर मान बाँधने के लिए lambda i=i: i का उपयोग करें।

python
double = lambda x: x * 2
double(5)   # 10

यह इसके समतुल्य है:

python
def double(x):
    return x * 2

ज़्यादातर मामलों के लिए, def का उपयोग करें। लैम्ब्डा का एक वास्तविक फ़ायदा है: आप उन्हें इनलाइन लिख सकते हैं, ठीक वहीं जहाँ आपको ज़रूरत हो, बिना नाम दिए। यही बात उन्हें sorted(), map(), और filter() के साथ उपयोगी बनाती है:

python
players = [("आर्या", 87), ("रोहन", 74), ("कविता", 92)]

sorted(players, key=lambda p: p[1])              # स्कोर के अनुसार क्रमबद्ध करें (आरोही)
sorted(players, key=lambda p: p[1], reverse=True)  # स्कोर के अनुसार क्रमबद्ध करें (अवरोही)

लैम्ब्डा के बिना, आपको केवल key= आर्ग्युमेंट के लिए एक नामित फ़ंक्शन परिभाषित करना पड़ता। लैम्ब्डा इरादे को स्थानीय और दृश्यमान रखता है।

लैम्ब्डा कई आर्ग्युमेंट्स ले सकते हैं:

python
add = lambda a, b: a + b
add(3, 4)   # 7

लैम्ब्डा का उपयोग कब करें: केवल तब जब यह एक सरल एक्सप्रेशन हो जो एक ही जगह उपयोग किया जाता है। यदि यह जटिल हो रहा है, या आपको इसे पुन: उपयोग करना है, तो उचित def लिखें। एक लैम्ब्डा जो कई ऑपरेटरों में फैला हो या जिसमें कंडीशनल्स की आवश्यकता हो, आमतौर पर def पर स्विच करने का संकेत है।

लिस्ट कॉम्प्रिहेंशन

Python में सबसे आम परिवर्तन: एक सीक्वेंस लें, हर आइटम के साथ कुछ करें, और एक नई लिस्ट प्राप्त करें। एक लिस्ट कॉम्प्रिहेंशन यह एक पठनीय पंक्ति में करता है: [expression for item in iterable]। आप if के साथ एक फ़िल्टर भी जोड़ सकते हैं।

लिस्ट कॉम्प्रिहेंशन बिल्ड-विद-अ-लूप पैटर्न का संक्षिप्त विकल्प हैं। ये ऑप्टिमाइज़्ड बाइटकोड में कंपाइल होते हैं और आम तौर पर .append() के साथ समतुल्य for लूप से तेज़ होते हैं। संरचना [expression for item in iterable if condition] है; if क्लॉज़ वैकल्पिक है।

लिस्ट कॉम्प्रिहेंशन समर्पित बाइटकोड में LIST_APPEND लूप में कंपाइल होते हैं, जो Python-स्तर के लूप में बार-बार list.append() कॉल्स से तेज़ है। वे Python 3 में एक नया स्कोप बनाते हैं (Python 2 के विपरीत), इसलिए लूप वैरिएबल लीक नहीं होता। नेस्टेड कॉम्प्रिहेंशन बाएँ से दाएँ और ऊपर से नीचे निष्पादित होते हैं: [expr for x in a for y in b] x के साथ बाहरी लूप के रूप में नेस्टेड for लूप के समतुल्य है।

लंबा तरीका:

python
numbers = [1, 2, 3, 4, 5]
squares = []
for n in numbers:
    squares.append(n ** 2)

लिस्ट कॉम्प्रिहेंशन:

python
squares = [n ** 2 for n in numbers]

संरचना हमेशा एक जैसी होती है: [expression for item in iterable]

python
scores    = [87, 42, 96, 55, 71]
scaled    = [s * 1.1 for s in scores]       # 10% बोनस लागू करें
as_grades = [f"{s}/100" for s in scores]    # प्रत्येक को प्रारूपित करें

एक शर्त के साथ फ़िल्टरिंग

केवल उन आइटम्स को शामिल करने के लिए एक if क्लॉज़ जोड़ें जो परीक्षण पास करते हैं। परिणाम एक नई लिस्ट है जिसमें केवल वे आइटम होते हैं जहाँ शर्त True है।

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

आउटपुट में if फ़िल्टर एक कंडीशनल एक्सप्रेशन से अलग है। [x for x in data if x > 0] फ़िल्टर करता है। [x if x > 0 else 0 for x in data] मैप करता है (शून्य पर क्लैम्प करता है)। आप दोनों को जोड़ सकते हैं: [x * 2 for x in data if x > 0]। कई if क्लॉज़ निहित and के साथ श्रृंखलाबद्ध होते हैं।

python
numbers  = [1, 2, 3, 4, 5, 6, 7, 8]
evens    = [n for n in numbers if n % 2 == 0]    # [2, 4, 6, 8]
odds     = [n for n in numbers if n % 2 != 0]    # [1, 3, 5, 7]
python
scores   = [87, 42, 96, 55, 71, 38]
passing  = [s for s in scores if s >= 60]    # [87, 96, 71]
failing  = [s for s in scores if s < 60]     # [42, 55, 38]

नेस्टेड कॉम्प्रिहेंशन

आप लिस्ट्स की लिस्ट को एक एकल लिस्ट में समतल करने के लिए कॉम्प्रिहेंशन को नेस्ट कर सकते हैं। इसे बाएँ से दाएँ पढ़ें: प्रत्येक पंक्ति के लिए, उस पंक्ति के प्रत्येक आइटम के लिए, आइटम को शामिल करें।

नेस्टेड कॉम्प्रिहेंशन बाएँ से दाएँ निष्पादित होते हैं। पहला for क्लॉज़ बाहरी लूप है, दूसरा भीतरी। वे एक 2D संरचना नहीं, एक एकल समतल परिणाम उत्पन्न करते हैं। यदि कॉम्प्रिहेंशन को एक नज़र में पढ़ना कठिन है, तो लूप्स को स्पष्ट रूप से लिखें।

नेस्टेड कॉम्प्रिहेंशन नेस्टेड लूप्स के रूप में निष्पादित होते हैं जिसमें पहला for सबसे बाहरी होता है। प्रत्येक लूप वैरिएबल का स्कोप बाद के क्लॉज़ में उपलब्ध होता है। कार्तीज़ियन उत्पादों के लिए, itertools.product अक्सर अधिक स्पष्ट होता है। मुख्य पठनीयता नियम: यदि कॉम्प्रिहेंशन को पार्स करने में एक सेकंड से अधिक समय लगता है, तो स्पष्ट लूप फ़ॉर्म बेहतर दस्तावेज़ीकरण है।

python
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat   = [item for row in matrix for item in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

इसे बाएँ से दाएँ पढ़ें: matrix की प्रत्येक row के लिए, row के प्रत्येक item के लिए, item को शामिल करें।

नेस्टेड कॉम्प्रिहेंशन जल्दी भ्रामक हो सकते हैं। यदि इसे पार्स करने में एक क्षण से अधिक समय लगता है, तो लूप्स को स्पष्ट रूप से लिखें।

डिक्ट कॉम्प्रिहेंशन

डिक्ट कॉम्प्रिहेंशन एक एक्सप्रेशन में एक डिक्शनरी बनाते हैं, लिस्ट कॉम्प्रिहेंशन के समान विचार का उपयोग करते हुए: {key: value for item in iterable}। लिस्ट कॉम्प्रिहेंशन की तरह ही if के साथ एक फ़िल्टर जोड़ें।

डिक्ट कॉम्प्रिहेंशन की-वैल्यू जोड़े उत्पन्न करने वाले किसी भी इटरेबल से एक नया डिक्ट बनाते हैं। सिंटैक्स {key_expr: val_expr for item in iterable if condition} है। लूप से डुप्लिकेट कीज़ चुपचाप अंतिम मान का उपयोग करती हैं। मौजूदा डिक्ट पर .items() डिक्ट कॉम्प्रिहेंशन के लिए सबसे आम स्रोत इटरेबल है।

डिक्ट कॉम्प्रिहेंशन समर्पित MAP_ADD बाइटकोड में कंपाइल होते हैं, जो लिस्ट कॉम्प्रिहेंशन के लिए LIST_APPEND के अनुरूप है। वे Python 3 में एक नया स्कोप बनाते हैं। की एक्सप्रेशन्स को हैशेबल मान उत्पन्न करना चाहिए; यदि एक की एक्सप्रेशन एक डुप्लिकेट उत्पन्न करता है, तो बाद का मान चुपचाप जीतता है। ऑर्डर्ड मर्ज सिमैंटिक्स के लिए, | ऑपरेटर (Python 3.9+) कॉम्प्रिहेंशन से अधिक स्वच्छ है।

python
names  = ["आर्या", "रोहन", "कविता"]
scores = [87, 74, 92]

score_map = {name: score for name, score in zip(names, scores)}
# {"आर्या": 87, "रोहन": 74, "कविता": 92}

एक फ़िल्टर के साथ:

python
passing = {name: score for name, score in score_map.items() if score >= 80}
# {"आर्या": 87, "कविता": 92}
python
words     = ["apple", "banana", "cherry"]
word_lens = {word: len(word) for word in words}
# {"apple": 5, "banana": 6, "cherry": 6}

सेट कॉम्प्रिहेंशन

सेट कॉम्प्रिहेंशन एक एक्सप्रेशन में एक सेट बनाते हैं, कर्ली ब्रेसेस के साथ और बिना कोलन के। चूँकि परिणाम एक सेट है, डुप्लिकेट्स स्वचालित रूप से हटा दिए जाते हैं।

सेट कॉम्प्रिहेंशन {expression for item in iterable} का उपयोग करते हैं और एक set उत्पन्न करते हैं। वे स्वचालित रूप से डिडुप्लिकेट करते हैं। इनका उपयोग तब करें जब आपको एक परिवर्तन से बना एक अद्वितीय कलेक्शन चाहिए, जहाँ क्रम मायने नहीं रखता।

सेट कॉम्प्रिहेंशन SET_ADD बाइटकोड में कंपाइल होते हैं। परिणाम एक अनऑर्डर्ड सेट है: एक्सप्रेशन से डुप्लिकेट मान चुपचाप विलीन हो जाते हैं। सेट कॉम्प्रिहेंशन लिस्ट या डिक्ट कॉम्प्रिहेंशन से कम आम हैं लेकिन एक एक्सप्रेशन में एक डिडुप्लिकेटेड परिवर्तन उत्पन्न करने का स्वच्छ तरीका हैं।

python
words   = ["apple", "banana", "cherry", "apple"]
unique  = {w.lower() for w in words}    # {"apple", "banana", "cherry"}

सेट कॉम्प्रिहेंशन का उपयोग तब करें जब आप अद्वितीय मान चाहते हैं और क्रम की परवाह नहीं करते।

जनरेटर एक्सप्रेशन

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

एक जनरेटर एक्सप्रेशन एक इटरेटर उत्पन्न करता है, कलेक्शन नहीं। यह आलसी ढंग से मानों की गणना करता है: अगला मान केवल अनुरोध करने पर उत्पन्न होता है। यह तब सबसे मूल्यवान होता है जब परिणाम तुरंत sum(), max(), या any() जैसे फ़ंक्शन द्वारा उपभोग किया जाता है, इसलिए पहले पूरी लिस्ट बनाने का कोई मतलब नहीं है।

जनरेटर एक्सप्रेशन एक कोड ऑब्जेक्ट में कंपाइल होते हैं और एक जनरेटर ऑब्जेक्ट लौटाते हैं। मान __next__ के माध्यम से आलसी ढंग से उत्पन्न होते हैं, जिससे इनपुट आकार की परवाह किए बिना मेमोरी उपयोग O(1) हो जाता है। वे इटरेटर प्रोटोकॉल में भाग लेते हैं और श्रृंखलाबद्ध किए जा सकते हैं। जब सीधे किसी ऐसे फ़ंक्शन को पास किया जाता है जो इटरेबल स्वीकार करता है, तो बाहरी कोष्ठक छोड़े जा सकते हैं। जनरेटर समाप्ति के बाद पुन: उपयोग नहीं किए जा सकते; यदि आपको कई बार इटरेट करने की आवश्यकता है, तो एक लिस्ट में मटीरियलाइज़ करें।

python
squares_gen = (n ** 2 for n in range(1000000))
python
total = sum(n ** 2 for n in range(1000000))   # sum() जनरेटर का उपभोग करता है

जब sum(), max(), min(), या any() जैसे फ़ंक्शन को सीधे एक जनरेटर पास करते हैं, तो आप अतिरिक्त कोष्ठक छोड़ सकते हैं:

python
total = sum(n ** 2 for n in range(1000))   # कोष्ठक का एक सेट, दो नहीं

अधिकांश रोज़मर्रा के कोड के लिए, लिस्ट कॉम्प्रिहेंशन ठीक हैं। जनरेटर का उपयोग तब करें जब आप बड़े डेटासेट या स्ट्रीमिंग डेटा को संसाधित कर रहे हों जहाँ सब कुछ मेमोरी में रखना बेकार होगा।

zip()

zip() दो या अधिक सीक्वेंस के आइटम्स को एक साथ जोड़ता है ताकि आप उन्हें समानांतर में लूप कर सकें। यह सबसे छोटे सीक्वेंस पर रुक जाता है। जब दो लिस्ट एक-दूसरे के अनुरूप हों, तो इंडेक्स प्रबंधित करने से बचने का यह स्वच्छ तरीका है।

zip() टपल्स का एक आलसी इटरेटर लौटाता है, अपने इनपुट इटरेबल्स को साथ-साथ उपभोग करता है। यह सबसे छोटे इनपुट पर रुक जाता है: लंबे सीक्वेंस चुपचाप काट दिए जाते हैं। उन सीक्वेंस के लिए जो लंबाई में भिन्न हो सकते हैं, itertools.zip_longest() छोटे वालों को एक निर्दिष्ट मान से भर देता है।

zip() एक zip ऑब्जेक्ट लौटाता है, एक आलसी इटरेटर जो प्रत्येक इनपुट इटरेटर पर एक साथ next() कॉल करता है। यह तब रुकता है जब कोई भी इटरेटर StopIteration उठाता है। सभी इनपुट आलसी ढंग से उपभोग किए जाते हैं: zip() स्वयं इनपुट आकार की परवाह किए बिना O(1) मेमोरी आवंटित करता है। zip(*iterable) मानक ट्रांसपोज़ ऑपरेशन है; * बाहरी इटरेबल को अलग आर्ग्युमेंट्स में अनपैक करता है।

python
names  = ["आर्या", "रोहन", "कविता"]
scores = [87, 74, 92]

for name, score in zip(names, scores):
    print(f"{name}: {score}")
# आर्या: 87
# रोहन: 74
# कविता: 92

zip() सबसे छोटे सीक्वेंस पर रुक जाता है। यदि आपके सीक्वेंस अलग-अलग लंबाई के हो सकते हैं, तो एक फिल वैल्यू के साथ itertools.zip_longest() का उपयोग करें।

ज़िप्ड जोड़ों की लिस्ट से वापस दो अलग-अलग लिस्ट में बदलने के लिए, zip(*pairs) का उपयोग करें:

python
pairs  = [("आर्या", 87), ("रोहन", 74), ("कविता", 92)]
names, scores = zip(*pairs)
# names = ("आर्या", "रोहन", "कविता")
# scores = (87, 74, 92)

यहाँ * क्या करता है?

*pairs लिस्ट को अलग आर्ग्युमेंट्स में अनपैक करता है: zip(*pairs) बन जाता है zip(("आर्या", 87), ("रोहन", 74), ("कविता", 92))* ऑपरेटर Functions अध्याय में कवर किया गया है।

zip() मैन्युअल रूप से इंडेक्स प्रबंधित किए बिना समानांतर में कई सीक्वेंस को इटरेट करने का स्वच्छ तरीका भी है:

python
before = [10, 20, 30]
after  = [15, 18, 35]

for b, a in zip(before, after):
    change = a - b
    print(f"{b} -> {a} ({'+' if change >= 0 else ''}{change})")

map() और filter()

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

map(func, iterable) एक आलसी इटरेटर लौटाता है जो प्रत्येक आइटम पर func लागू करता है। filter(func, iterable) उन आइटम्स का एक आलसी इटरेटर लौटाता है जिनके लिए func truthy है। दोनों कॉम्प्रिहेंशन से पहले के हैं। नए कोड में कॉम्प्रिहेंशन को प्राथमिकता दें; map() का उपयोग तब करें जब आपके पास पहले से एक नामित फ़ंक्शन हो जो आपकी ज़रूरत का काम करता है।

map() और filter() Python 3 में आलसी इटरेटर्स (लिस्ट नहीं) लौटाते हैं। map(f, it) (f(x) for x in it) के समतुल्य है। filter(pred, it) (x for x in it if pred(x)) के समतुल्य है। नामित फ़ंक्शन्स के लिए, list(map(int, strings)) इडियोमैटिक है क्योंकि यह "map int over strings" के रूप में पढ़ा जाता है; समतुल्य कॉम्प्रिहेंशन [int(s) for s in strings] भी समान रूप से मान्य है।

python
numbers = [1, 2, 3, 4, 5]

list(map(lambda x: x ** 2, numbers))         # [1, 4, 9, 16, 25]
list(filter(lambda x: x % 2 == 0, numbers))  # [2, 4]

कॉम्प्रिहेंशन को प्राथमिकता दें; वे अधिकांश Python डेवलपर्स के लिए अधिक पठनीय हैं। map() का उपयोग तब करें जब आपके पास एक नामित फ़ंक्शन हो जो पहले से मौजूद है:

python
strings = ["1", "2", "3"]
numbers = list(map(int, strings))   # [1, 2, 3] (यहाँ कॉम्प्रिहेंशन से अधिक स्वच्छ)

व्यवहार में

एक प्लेयर लिस्ट को पासिंग स्कोर तक फ़िल्टर करें, sorted और एक लैम्ब्डा के साथ स्कोर के अनुसार रैंक करें, फिर गणना की गई स्थितियों के साथ प्रिंट करें:

python
players = [
    {"name": "आर्या", "score": 87},
    {"name": "रोहन",   "score": 42},
    {"name": "कविता", "score": 96},
    {"name": "विकास",  "score": 55},
]

passing   = [p for p in players if p["score"] >= 60]
ranked    = sorted(passing, key=lambda p: p["score"], reverse=True)
score_map = {p["name"]: p["score"] for p in ranked}

for i, (name, score) in enumerate(score_map.items(), start=1):
    print(f"{i}. {name}: {score}")

एक उपयोगकर्ता लिस्ट को सक्रिय एडमिन्स के लिए फ़िल्टर करें, एक id-से-नाम लुकअप डिक्ट बनाएँ, और एक-एक पास में क्रमबद्ध नाम एकत्र करें:

python
raw_users = [
    {"id": 1, "name": "आर्या", "role": "admin", "active": True},
    {"id": 2, "name": "रोहन",   "role": "user",  "active": False},
    {"id": 3, "name": "कविता", "role": "admin", "active": True},
    {"id": 4, "name": "विकास",  "role": "user",  "active": True},
]

active_admins = [u for u in raw_users if u["active"] and u["role"] == "admin"]
id_map        = {u["id"]: u["name"] for u in raw_users}
names         = sorted(u["name"] for u in raw_users if u["active"])

print(f"Active admins: {[u['name'] for u in active_admins]}")
print(f"All active: {names}")

zip का उपयोग करके फ़ीचर नामों को महत्व स्कोर के साथ जोड़ें, एक डिक्ट कॉम्प्रिहेंशन बनाएँ, एक लैम्ब्डा के साथ क्रमबद्ध करें, और दूसरे कॉम्प्रिहेंशन में मानों को सामान्य करें:

python
feature_names = ["age", "income", "score", "tenure"]
importances   = [0.12, 0.34, 0.28, 0.26]

feat_dict = {f: i for f, i in zip(feature_names, importances)}
top_feats = sorted(feat_dict.items(), key=lambda x: x[1], reverse=True)[:2]

print("Top 2 features:")
for name, score in top_feats:
    print(f"  {name}: {score:.2f}")

# 1.0 के योग के लिए सामान्य करें (मान यहाँ पहले से 1 का योग देते हैं, लेकिन एक पैटर्न के रूप में दिखाया गया है)
total      = sum(feat_dict.values())
normalised = {k: round(v / total, 4) for k, v in feat_dict.items()}
print(f"Normalised: {normalised}")

zip मध्यवर्ती टपल्स बनाए बिना दोनों लिस्ट्स को जोड़ता है। डिक्ट कॉम्प्रिहेंशन मैपिंग को एक एक्सप्रेशन में बनाता है। सॉर्ट लैम्ब्डा एक नामित की फ़ंक्शन से बचता है। सामान्यीकरण कॉम्प्रिहेंशन मूल डिक्ट को बदले बिना मानों को रूपांतरित करता है।