2011-05-28 15 views
5

वहाँ एक itemgetter विकल्प है कि नेस्टेड टपल मूल्य अर्क लिखने की तुलना में एक नेस्टेड टपल मूल्यों से एक सूची सॉर्ट करने के लिए एक बेहतर तरीका है:क्रमबद्ध सूची को महत्व देता

def deep_get(*idx): 
    def g(t): 
     for i in idx: t = t[i] 
     return t 
    return g 

>>> l = [((2,1), 1),((1,3), 1),((3,6), 1),((4,5), 2)] 
>>> sorted(l, key=deep_get(0,0)) 
[((1, 3), 1), ((2, 1), 1), ((3, 6), 1), ((4, 5), 2)] 
>>> sorted(l, key=deep_get(0,1)) 
[((2, 1), 1), ((1, 3), 1), ((4, 5), 2), ((3, 6), 1)] 

मैं रचना का उपयोग कर के बारे में सोचा है, लेकिन यह है नहीं मानक पुस्तकालय में:

sorted(l, key=compose(itemgetter(1), itemgetter(0)) 

वहाँ कुछ मैं libs में याद किया है कि इस कोड अच्छे होगा है?

कार्यान्वयन 100k वस्तुओं के साथ उचित रूप से काम करना चाहिए।

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

+0

नहीं है कोई भी जिसे मैं जानता हूं। आपका दृष्टिकोण अच्छा है क्योंकि यह आईएमएचओ है। –

+0

"कार्यान्वयन 100k वस्तुओं के साथ उचित रूप से काम करना चाहिए।" - यह लाइन अनावश्यक है; 'सॉर्ट' का उपयोग करने वाले सभी कार्यान्वयन 100k आइटम – ninjagecko

+0

@ninjagecko के साथ उचित रूप से काम करेंगे यदि आप 3 आइटम या 100k या 1T सॉर्ट करते हैं तो कार्यान्वयन अलग होगा। –

उत्तर

8

हाँ, तुम सिर्फ एक key=lambda x: x[0][1]

+0

'itemgetter (0)' lambda x: x [0] 'से तेज है? 'लिखें (itemgetter (1), itemgetter (0))', 'lambda x: x [0] [1] 'और' deep_get' समान प्रदर्शन विशेषताओं? –

+0

लैम्ब्डा लगभग निश्चित रूप से उन सभी की तुलना में तेज़ होगा, लेकिन यह अभी भी 'ओ (एन लॉग (एन)) है जो सॉर्टिंग के कारण है इसलिए मैं इसके बारे में ज्यादा चिंता नहीं करता; – ninjagecko

+1

को अनुकूलित करने के लिए शायद बेहतर चीजें हैं, मुझे लगता है कि आइटमेटर लैम्ब्डा से तेज़ होगा, क्योंकि यह सी में लिखा गया है। आपको लगता है कि लैम्ब्डा तेज क्यों है? – utdemir

2

आपका दृष्टिकोण इस्तेमाल कर सकते हैं कि आपके पास डेटा संरचना को देखते हुए काफी अच्छा है।

एक अन्य दृष्टिकोण एक और संरचना का उपयोग करना होगा।

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

>>> arr = numpy.array([((2,1), 1),((1,3), 1),((3,6), 1),((4,5), 2)], 
        dtype=[('pos', [('a', int), ('b', int)]), ('count', int)]) 
>>> print numpy.sort(arr, order=['count', 'pos']) 
[((1, 3), 1) ((2, 1), 1) ((3, 6), 1) ((4, 5), 2)] 

यह (यह सी में लागू हो जाता है) बहुत तेजी से है।

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

0

मैंने दो समान समाधानों की तुलना की। ,

def sort_one(d): 
    result = d.items() 
    result.sort(key=lambda x: (-x[1], x[0])) 
    return result 

नोट x[1] पर शून्य है क्योंकि आप चाहते हैं प्रकार गिनती पर उतरते जा रहे हैं: पहले एक एक सरल लैम्ब्डा उपयोग करता है।

दूसरा व्यक्ति इस तथ्य का लाभ उठाता है कि पाइथन में sort स्थिर है। सबसे पहले, हम (a, b) (आरोही) द्वारा क्रमबद्ध करें। फिर हम तरह से गिनती, उतरते:

def sort_two(d): 
    result = d.items() 
    result.sort() 
    result.sort(key=itemgetter(1), reverse=True) 
    return result 

पहले एक 100k मदों के लिए 10-20% तेजी से (छोटे और बड़े दोनों डेटासेट पर), और दोनों 0.5sec के तहत पूरा मेरी Q6600 (एक कोर प्रयोग किया जाता) पर है । तो tuples के निर्माण से परहेज बहुत मदद करने के लिए प्रतीत नहीं होता है।

1

यह आपके दृष्टिकोण का एक छोटा तेजी संस्करण हो सकता है:

l = [((2,1), 1), ((1,3), 1), ((3,6), 1), ((4,5), 2)] 

def deep_get(*idx): 
    def g(t): 
     return reduce(lambda t, i: t[i], idx, t) 
    return g 

>>> sorted(l, key=deep_get(0,1)) 
[((2, 1), 1), ((1, 3), 1), ((4, 5), 2), ((3, 6), 1)] 

कौन सा के लिए छोटा किया जा सकता है:

def deep_get(*idx): 
    return lambda t: reduce(lambda t, i: t[i], idx, t) 

या यहाँ तक कि बस लिखा-आउट:

sorted(l, key=lambda t: reduce(lambda t, i: t[i], (0,1), t)) 
संबंधित मुद्दे