पायथन 3 में एक कस्टम तुलना फ़ंक्शन का उपयोग कैसे करें?


98

में अजगर 2.x , मैं छाँटे गए और .sort कार्यों के लिए कस्टम समारोह गुजर सकता है

>>> x=['kar','htar','har','ar']
>>>
>>> sorted(x)
['ar', 'har', 'htar', 'kar']
>>> 
>>> sorted(x,cmp=customsort)
['kar', 'htar', 'har', 'ar']

क्योंकि, मेरी भाषा में, सहमति इस आदेश के साथ आती है

"k","kh",....,"ht",..."h",...,"a"

लेकिन पायथन 3.x में , ऐसा लगता है कि मैं cmpकीवर्ड पास नहीं कर सका

>>> sorted(x,cmp=customsort)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'cmp' is an invalid keyword argument for this function

क्या कोई विकल्प है या मुझे अपना स्वयं का क्रमबद्ध फ़ंक्शन भी लिखना चाहिए?

नोट: मैंने "k", "kh", आदि का उपयोग करके सरलीकृत किया है। वास्तविक वर्ण यूनिकोड हैं और यहां तक ​​कि अधिक जटिल हैं, कभी-कभी स्वर हैं पहले और बाद में सहमति के बाद, मैंने कस्टम तुलनात्मक फ़ंक्शन किया है, ताकि भाग ठीक हो। केवल समस्या यह है कि मैं अपने कस्टम तुलना फ़ंक्शन को सॉर्ट या .Sort में नहीं दे सका


क्या आपने अभी-अभी कोशिश की है sorted(x)?
साइलेंटगॉस्ट

@SilentGhost, यह सुनिश्चित करने के लिए, मैंने बस फिर से कोशिश की, निश्चित रूप से काम नहीं कर रहा, क्योंकि मेरी मूल भाषा छँटाई करने के लिए ऑपरेशन सिस्टम द्वारा स्थानीय सूची समर्थन में नहीं है।
आप

1
आप एक महत्वपूर्ण कार्य के रूप में अपने cmp को लपेट सकते हैं। Cmp_to_key के लिए HowToSorting साइट खोजें।
फ्रैंक

यहाँ कुछ इसी तरह के stackoverflow.com/questions/49327344/…
Eziz Durdyyev

जवाबों:


50

keyतर्क का उपयोग करें (और अपने पुराने फ़ंक्शन को फ़ंक्शन में कनवर्ट करने के लिए नुस्खा का पालन करें )।cmpkey

functoolsdocs.python.org/3.6/library/functools.html#functools.cmp_to_keycmp_to_key पर एक फ़ंक्शन का उल्लेख किया गया है


+1, ऐसा लगता है कि रेसिपी मुझे वर्कअराउंड देती है, लेकिन मुझे लगता है कि मैं < > = मिडिल मैन के सभी तुलना ऑपरेटरों को पास करके कुछ प्रदर्शन खोने जा रहा हूं , क्योंकि मेरी मूल कस्टम सॉर्ट सी में लिखी गई है, इसमें लगभग 1 / 2x की गति थी डिफ़ॉल्ट प्रकार।
आप

2
(बस आपकी प्रोफ़ाइल को देखा गया) आपकी कंपनी Google और StackOverflow की पहुंच को रोक रही है? वे कितने मूर्ख हो सकते हैं? लेकिन आपकी प्रतिक्रिया के बारे में: मुझे वास्तविक प्रदर्शन में कमी में दिलचस्पी होगी। क्या आप timeitइसे कर सकते हैं ?
टिम पीटरज़

4
मैंने कुछ बेंचमार्क किए हैं, जैसे कि कस्टम सी तुलना फ़ंक्शन को सीधे पास करने की तुलना में लगभग 4x धीमा लगता है।
आप

2
क्या होगा अगर मुझे एक महत्वपूर्ण फ़ंक्शन और एक सीएमपी फ़ंक्शन दोनों की आवश्यकता है? मैं प्रत्येक शब्दकोश में एक कस्टम कुंजी द्वारा शब्दकोशों की एक सूची को सॉर्ट करना चाहता हूं। sorted_rows = sorted(rows, key=itemgetter('name'), cmp=locale.strxfrm)TypeError देता है: 'cmp' इस फ़ंक्शन के लिए एक अमान्य कीवर्ड तर्क है, Python 3.2 में :(
bitek

4
फंक्शनलबल्स का मानक पुस्तकालय में एक cmp_to_key फ़ंक्शन है: docs.python.org/3.6/library/functools.html
मार्टीन फ़िक्मैन


17

सीमा शुल्क () के बजाय, आपको एक फ़ंक्शन की आवश्यकता होती है जो प्रत्येक शब्द को उस चीज़ में अनुवाद करता है जिसे पायथन पहले से जानता है कि कैसे छाँटना है। उदाहरण के लिए, आप प्रत्येक शब्द को उन संख्याओं की सूची में अनुवाद कर सकते हैं, जहाँ प्रत्येक संख्या आपके वर्णमाला में होने वाले प्रत्येक अक्षर का प्रतिनिधित्व करती है। कुछ इस तरह:

my_alphabet = ['a', 'b', 'c']

def custom_key(word):
   numbers = []
   for letter in word:
      numbers.append(my_alphabet.index(letter))
   return numbers

x=['cbaba', 'ababa', 'bbaa']
x.sort(key=custom_key)

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


धन्यवाद +1, मुझे लगता है कि आईसीयू तरीका है। लेकिन चूंकि मेरी भाषा में शब्द सेपरेटर नहीं हैं और मानक रोमानी नियम नहीं हैं, इसलिए मुझे लगता है कि शोध के लिए समय लगेगा।
आप

9

एक पूर्ण python3 cmp_to_key लैम्ब्डा उदाहरण:

from functools import cmp_to_key

nums = [28, 50, 17, 12, 121]
nums.sort(key=cmp_to_key(lambda x, y: 1 if str(x)+str(y) < str(y)+str(x) else -1))

सामान्य वस्तु छँटाई की तुलना करें:

class NumStr:
    def __init__(self, v):
        self.v = v
    def __lt__(self, other):
        return self.v + other.v < other.v + self.v


A = [NumStr("12"), NumStr("121")]
A.sort()
print(A[0].v, A[1].v)

A = [obj.v for obj in A]
print(A)

4

मुझे नहीं पता कि यह मदद करेगा, लेकिन आप localeमॉड्यूल की जांच कर सकते हैं । ऐसा लगता है कि आप अपनी भाषा में लोकेल सेट कर सकते हैं और locale.strcollअपनी भाषा के सॉर्टिंग नियमों का उपयोग करके तार की तुलना कर सकते हैं।


यह लोकप्रिय भाषाओं के लिए सही है, लेकिन मेरी भाषा पूरी तरह से ऑपरेशन सिस्टम, ICU और unicode.org द्वारा समर्थित नहीं है, इसलिए प्रश्न से बाहर है, लेकिन अच्छे सुझाव के लिए +1।
आप

-2

keyइसके बजाय तर्क का उपयोग करें । यह एक फ़ंक्शन लेता है जो संसाधित होने के लिए मूल्य लेता है और एक एकल मान देता है जिसके द्वारा उपयोग करने के लिए कुंजी दी जाती है।

sorted(x, key=somekeyfunc)

3
कुंजी केवल एक पैरामीटर फ़ंक्शन को स्वीकार करती है, cmp में 2 पैरामीटर हैं, वे अलग-अलग व्यवहार हैं। और मैंने अभी-अभी परीक्षण किया, त्रुटि हुई, क्योंकि कुंजीशब्द केवल एक पैरामीटर से गुजरता है,TypeError: customsort() takes exactly 2 positional arguments (1 given)
आप
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.