कस्टम पायथन सूची छँटाई


93

मैं अपना कुछ पुराना कोड वापस ले रहा था और इस पर आया:

alist.sort(cmp_items)

def cmp_items(a, b):
    if a.foo > b.foo:
        return 1
    elif a.foo == b.foo:
        return 0
    else:
        return -1

कोड काम करता है (और मैंने इसे कुछ 3 साल पहले लिखा था!) ​​लेकिन मैं पायथन डॉक्स में कहीं भी इस बात को प्रलेखित नहीं कर पाया और हर कोई sorted()कस्टम छँटाई को लागू करने के लिए उपयोग करता है। क्या कोई समझा सकता है कि यह क्यों काम करता है?


sorted()और sort()उसी तरह से कस्टम छँटाई की पेशकश करते हैं, सम्मेलन बुलाने में अंतर को मापता है।
रसेल बोरोगोव

2
दरअसल, ऐसा क्या होता है कि फंक्शन keyपास करने के लिए पैरामीटर का इस्तेमाल करना ज्यादा पसंद किया जाता है cmp। (बाद में पायथन 3 में भी लागू नहीं किया गया है)
jsbueno

यह अस्पष्ट है, इस बात पर निर्भर करता है कि सूची में मौजूद वस्तुएं क्या थीं; आपके कोड के लिए आवश्यक है कि उनके पास एक विशेषता हो foo, अन्यथा यह फूल जाता है। __lt__()अपनी कक्षा के लिए एक कस्टम पद्धति को परिभाषित करने के लिए बेहतर है , sorted()और फिर list.sort()आउट-ऑफ-द-बॉक्स काम करेगा। (Btw, परिभाषित करने के लिए आवश्यकता नहीं वस्तुओं __cmp__(), बस __lt__()यह देखें
एसएमसीआई

जवाबों:


60

यह यहाँ प्रलेखित है

तुलना को नियंत्रित करने के लिए सॉर्ट () विधि वैकल्पिक तर्क लेती है।

सीएमपी दो तर्कों (सूची आइटम) के एक कस्टम तुलनात्मक फ़ंक्शन को निर्दिष्ट करता है जो एक नकारात्मक, शून्य या सकारात्मक संख्या पर निर्भर करता है, जो इस बात पर निर्भर करता है कि क्या पहला तर्क दूसरे तर्क की तुलना में छोटा, बराबर या बड़ा है: cmp = lambda x, y : cmp (x.lower (), y.lower ())। कोई डिफ़ॉल्ट मान नहीं है।


धन्यवाद mi82 मैं यहाँ जाँच कर रहा था और इसे विधि हस्ताक्षर docs.python.org/tutorial/datastructures.html
Lorenzo

मुझे आपके द्वारा लिंक किए गए पृष्ठ पर एक ही टेक्स्ट दिखाई नहीं देता है। क्या प्रलेखन बदल गया? इसके अलावा, जब मैं उपयोग करने की कोशिश करता cmpहूं, मुझे मिलता है TypeError: 'cmp' is an invalid keyword argument for this function। यहाँ क्या हो रहा है?
HelloGoodbye

1
@HelloGoodbye सॉर्ट () के पास पाइथन 3 में cmp तर्क नहीं है। यह एक पुराना उत्तर है जब डॉक्स लिंक Python 2 के लिए था। आप यहां पुराने डॉक्स पा सकते हैं या इसके बारे में अधिक पढ़ सकते हैं । यदि आप पायथन 3 का उपयोग कर रहे हैं, तो इसके बजाय मुख्य तर्क का उपयोग करें।
मीलों'२

और क्या होगा यदि आप वास्तव में एक तुलनात्मक कार्य प्रदान करना चाहते हैं? मैं एक स्ट्रिंग में संख्याओं का इलाज करना चाहता हूं (किसी भी लंबाई का, लालच से निकाला गया) प्रतीकों के रूप में, व्यक्तिगत पात्रों के साथ कैसे व्यवहार किया जाता है। मुझे पता है कि यदि मैं एक तुलनात्मक कार्य प्रदान कर सकता हूं, तो कैसे प्राप्त कर सकता हूं, लेकिन यदि मुझे एक महत्वपूर्ण कार्य प्रदान करना है तो नहीं। इसे क्यों बदला गया?
HelloGoodbye

मुझे लगता है कि यह अभी भी प्राप्त किया जा सकता है यदि स्ट्रिंग में निहित प्रत्येक संख्या एन्कोडिंग का उपयोग करके एन्कोडेड है जो संख्याओं को लेक्सिकोग्राफिक रूप से आदेश देता है, जैसे कि लेवेन्स्चिन कोडिंग । लेकिन मैं इसे इस तथ्य के लिए एक वर्कअराउंड के रूप में अधिक मानता हूं कि sortपायथन 3 में तर्क के रूप में तुलनात्मक कार्य नहीं करता है, और न ही कुछ ऐसा है जो मैं वास्तव में करना चाहता हूं।
HelloGoodbye

104

एक साइड नोट के रूप में, यहाँ एक ही छँटाई को लागू करने के लिए एक बेहतर विकल्प है:

alist.sort(key=lambda x: x.foo)

या वैकल्पिक रूप से:

import operator
alist.sort(key=operator.attrgetter('foo'))

की जाँच करें छंटाई कैसे , यह बहुत उपयोगी है।


1
ऑपरेटर के बारे में टीआईएल, बहुत उपयोगी है।
ffledgling

13

इस उदाहरण की तरह। आप इस सूची को क्रमबद्ध करना चाहते हैं।

[('c', 2), ('b', 2), ('a', 3)]

उत्पादन:

[('a', 3), ('b', 2), ('c', 2)]

आपको दूसरे आइटम द्वारा टुपल्स को सॉर्ट करना चाहिए, फिर पहला:

def letter_cmp(a, b):
    if a[1] > b[1]:
        return -1
    elif a[1] == b[1]:
        if a[0] > b[0]:
            return 1
        else:
            return -1
    else:
        return 1

आखिरकार:

केवल sort(letter_cmp)


4
यह कैसे पता चलता है कि किस सूची को क्रमबद्ध करना है?
कैमरून मोंक्स

2
@CameronMonks yourList.sort (letter_cmp)
Minyc510

7

यह पायथन 3 में काम नहीं करता है।

यद्यपि पुरानी शैली की तुलनात्मक कार्यों को करने के लिए आप कई प्रकार के कार्य cmp_to_key का उपयोग कर सकते हैं।

from functools import cmp_to_key

def cmp_items(a, b):
    if a.foo > b.foo:
        return 1
    elif a.foo == b.foo:
        return 0
    else:
        return -1

cmp_items_py3 = cmp_to_key(cmp_items)

alist.sort(cmp_items_py3)

1

Python3 में आप लिख सकते हैं:

from functools import cmp_to_key

def cmp_items(a, b):
    if a.foo > b.foo:
        return 1
    elif a.foo == b.foo:
        return 0
    else:
        return -1

alist = sorted(alist, key=cmp_to_key(cmp_items))

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