कस्टम तुलना छँटाई, के रूप में मौजूदा जवाब में सुझाव के लिए काम करता है, यह आरोही के मिश्रण में सॉर्ट करने के लिए आसान कर सकता हूँ और अवरोही आदेश - लेकिन उनके पास गंभीर प्रदर्शन समस्याएं हैं और उन्हें केवल पसंदीदा अनुकूलन दृष्टिकोण छोड़कर पाइथन 3 में हटा दिया गया है - कस्टम कुंजी-निष्कर्षण फ़ंक्शंस ... बहुत तेज़, अपेक्षाकृत दुर्लभ उपयोग के मामले के लिए उपयोग करने के लिए अधिक नाजुक मिश्रित आरोही/अवरोही प्रकार।
अजगर 2.*
, जो अनुकूलन के दोनों तरह (नहीं sort
या sorted
:-), एक कस्टम तुलना समारोह एक cmp=
नामित तर्क के रूप में पारित किया जा सकता करने के लिए एक ही कॉल में दोनों का समर्थन करता है में; या, एक कस्टम कुंजी निष्कर्षण समारोह key=
नामित तर्क के रूप में पारित किया जा सकता है। पायथन 3.*
में, केवल बाद का विकल्प उपलब्ध है।
यह महत्वपूर्ण रूप से कुंजी निष्कर्षण दृष्टिकोण को समझने लायक है, भले ही आपको लगता है कि आपने अपनी समस्या को केवल कस्टम-तुलना दृष्टिकोण के साथ हल किया है: न केवल प्रदर्शन के लिए, बल्कि भविष्य के लिए साक्ष्य (पायथन 3) और सामान्यता के लिए (key=
दृष्टिकोण min
, max
, itertools.groupby
पर भी लागू होता है ... cmp=
दृष्टिकोण से कहीं अधिक सामान्य!)।
कुंजी-निष्कर्षण बहुत सरल है जब सभी प्रमुख उप-क्षेत्रों को समान तरीके से क्रमबद्ध किया जाना चाहिए (सभी आरोही, या सभी अवरोही) - आप उन्हें निकालें; यह अभी भी बहुत आसान है अगर उप-क्षेत्र "दूसरी तरफ" जाते हैं तो संख्याएं होती हैं (आप निकालने के दौरान बस अपना संकेत बदलते हैं); नाजुक मामला बिल्कुल आपके पास है - एकाधिक स्ट्रिंग फ़ील्ड जिन्हें तुलनात्मक तरीकों से तुलना की जानी चाहिए।
एक अपनी समस्या का समाधान करने के लिए यथोचित सरल दृष्टिकोण एक छोटे से शिम वर्ग है:
class Reverser(object):
def __init__(self, s): self.s = s
def __lt__(self, other): return other.s < self.s
def __eq__(self, other): return other.s == self.s
नोट आप केवल __lt__
और __eq__
(<
और ==
ऑपरेटरों) की आपूर्ति करने के लिए है कि - sort
और दोस्तों के सभी अन्य संश्लेषण तुलना, यदि आवश्यक हो, उन दोनों के आधार पर।
तो, यह थोड़ा सहायक उपकरण के साथ सशस्त्र, हम आसानी से आगे बढ़ सकते हैं ...:
def getkey(tup):
a, b = tup[0].split('_')
return Reverser(a), b
my_list.sort(key=getkey)
जैसा कि आप देख, एक बार आप reverser और प्रमुख निष्कर्षण अवधारणाओं "मिल", आप अनिवार्य रूप से करने के लिए कोई कीमत अदा कस्टम तुलना के बजाय कुंजी निष्कर्षण का उपयोग करना: कोड जो मैं सुझाता हूं वह रिवर्सर क्लास के लिए 4 कथन है (जिसे आप एक बार लिख सकते हैं और अपने "गुड्स बैग" मॉड्यूल में कहीं भी डाल सकते हैं), तीन मुख्य निष्कर्षण समारोह के लिए, और निश्चित रूप से एक के लिए sort
या sorted
कॉल - सबसे कॉम्पैक्ट रूप में कस्टम तुलना दृष्टिकोण के कुल आठ बनाम 4 + 1 == 5 (यानी एक साइन परिवर्तन के साथ या तो सीएमपी का उपयोग करने वाला, या स्वैप तर्क के साथ सीएमपी एनटीएस)। तीन कथन कुंजी-निष्कर्षण के फायदे के लिए भुगतान करने के लिए बहुत अधिक मूल्य नहीं हैं! -
प्रदर्शन स्पष्ट रूप से ऐसी छोटी सूची के साथ एक बड़ा मुद्दा नहीं है, लेकिन यहां तक कि मामूली लंबे समय तक (10 गुना) एक ...: अच्छी तरह से लायक "8 लाइनों की मामूली कीमत नहीं बल्कि -
# my_list as in the Q, my_cmp as per top A, getkey as here
def bycmp():
return sorted(my_list*10, cmp=my_cmp)
def bykey():
return sorted(my_list*10, key=getkey)
...
$ python -mtimeit -s'import so' 'so.bykey()'
1000 loops, best of 3: 548 usec per loop
$ python -mtimeit -s'import so' 'so.bycmp()'
1000 loops, best of 3: 995 usec per loop
Ie, key=
दृष्टिकोण पहले से ही लगभग दो बार (सूची को क्रमबद्ध करने दोगुनी गति से) के एक प्रदर्शन लाभ जब एक 50 मदों की सूची पर काम कर दिखाया जा रहा है 5 से अधिक ", विशेष रूप से मैंने पहले उल्लेख किए गए सभी अन्य फायदों के साथ!
वाह, मुझे आपका समाधान पसंद है। मुझे नहीं पता था कि सीएमपी = दृष्टिकोण के पास ऐसा जुर्माना था। –
@Steven, tx - yep, सभी को समझ में नहीं आता कि क्यों cmp = पायथन 3 में हटा दिया गया था (एक "आकर्षक उपद्रव" के रूप में जो लोगों को प्रदर्शन दंड भुगतने में बाधा डालता है!), यही कारण है कि मैंने इस विस्तृत स्पष्टीकरण को पोस्ट किया, इसलिए धन्यवाद पुष्टि करने के लिए यह मदद कर सकता है! -) –
@Alex: मैं * आपके * उत्तरों में से किसी एक को संपादित करने में संकोच करता हूं लेकिन शायद my_list.key (cmp = my_cmp) my_list.sort (key = getkey) होना चाहिए? –