2010-04-19 23 views
46

में अल्फा न्यूमेरिक सेट सॉर्ट करने के लिए मैं कैसे छँटाई करने के बाद एक सेटअजगर

set(['booklet', '4 sheets', '48 sheets', '12 sheets']) 

है मैं इसे पसंद

4 sheets, 
12 sheets, 
48 sheets, 
booklet 

किसी भी विचार कृपया

उत्तर

43

लघु और मीठा:

sorted(data, key=lambda item: (int(item.partition(' ')[0]) 
           if item[0].isdigit() else float('inf'), item)) 

इस संस्करण:

  • अजगर 2 और अजगर 3 में काम करता है, क्योंकि:
    • यह आप तार तुलना स्वीकार नही करता और पूर्णांक (जो पायथन 3 में काम नहीं करेगा)
    • यह sorted करने के लिए cmp पैरामीटर का उपयोग नहीं करता
  • (जो अजगर 3 में मौजूद नहीं है) स्ट्रिंग ओर से सॉर्ट होगा अगर मात्रा

आप मुद्रित चाहते हैं उत्पादन बिल्कुल बराबर हैं अपने उदाहरण है, तो में वर्णित हैं:

data = set(['booklet', '4 sheets', '48 sheets', '12 sheets']) 
r = sorted(data, key=lambda item: (int(item.partition(' ')[0]) 
            if item[0].isdigit() else float('inf'), item)) 
print ',\n'.join(r) 
+1

ग्रेट उत्तर डैनियल – mmrs151

1
>>> a = set(['booklet', '4 sheets', '48 sheets', '12 sheets']) 
>>> def ke(s): 
    i, sp, _ = s.partition(' ') 
    if i.isnumeric(): 
     return int(i) 
    return float('inf') 

>>> sorted(a, key=ke) 
['4 sheets', '12 sheets', '48 sheets', 'booklet'] 
1

सेट स्वाभाविक हैं देखना चाहते हैं अन-आदेश दिया। आपको एक ही सामग्री के साथ एक सूची बनाने और उसे क्रमबद्ध करने की आवश्यकता होगी।

+2

नहीं सच - अनुसार क्रमबद्ध() में निर्मित किसी भी क्रम लेने के लिए और एक क्रमबद्ध सूची वापस आ जाएगी । – PaulMcG

+3

तो सूची बनाने और इसे क्रमबद्ध करने के बजाय, आप क्रमबद्ध सूची बनाने के लिए एक बिल्टिन का उपयोग करते हैं .... हाँ, मैं रास्ता बंद था। – Rakis

1

SilentGhost के जवाब के आधार पर: प्राकृतिक तरह के बारे में

In [4]: a = set(['booklet', '4 sheets', '48 sheets', '12 sheets']) 

In [5]: def f(x): 
    ...:  num = x.split(None, 1)[0] 
    ...:  if num.isdigit(): 
    ...:   return int(num) 
    ...:  return x 
    ...: 

In [6]: sorted(a, key=f) 
Out[6]: ['4 sheets', '12 sheets', '48 sheets', 'booklet'] 
83

Jeff Atwood बात करती है और एक तरह से का एक उदाहरण पायथन में यह करने के लिए देता है।

इस तरह
import re 

def sorted_nicely(l): 
    """ Sort the given iterable in the way that humans expect.""" 
    convert = lambda text: int(text) if text.isdigit() else text 
    alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ] 
    return sorted(l, key = alphanum_key) 

उपयोग:: यहाँ उस पर मेरी भिन्नता है

s = set(['booklet', '4 sheets', '48 sheets', '12 sheets']) 
for x in sorted_nicely(s): 
    print(x) 

आउटपुट:

इस विधि का
4 sheets 
12 sheets 
48 sheets 
booklet 

एक लाभ यह है कि यह सिर्फ जब तार से काम नहीं करता है रिक्त स्थान से अलग हैं। यह अन्य विभाजकों के लिए भी काम करेगा जैसे कि संस्करण संख्याओं में अवधि (उदाहरण के लिए 1.9.1 1.10.0 से पहले आता है)।

+0

हाय जेफ, बहुत बहुत धन्यवाद। यह वहीं है जिसे मैं ढूंढ रहा था। शुभकामनाएं। – mmrs151

+2

क्या टुपल में पहले मान के आधार पर टुपल्स की सूची के लिए इसे संशोधित करना संभव है?उदाहरण: '[('बी', 0), ('0', 1), ('ए', 2)] 'को' [('0', 1), ('ए', 2) में क्रमबद्ध किया गया है, ('बी', 0)] ' – paragbaxi

+3

यह फ़ंक्शन केस संवेदनशील है। ऊपरी केस तारों को प्राथमिकता दी जाएगी। इसे ठीक करने के लिए 're.split' में' .lower() 'to' key' जोड़ें। – zamber

6

तारों को क्रमबद्ध करने के लिए स्ट्रिंग को संख्यात्मक भागों और गैर-संख्यात्मक भागों में विभाजित करना और पाइथन टुपल सॉर्ट ऑर्डर का उपयोग करना एक आसान तरीका है।

import re 
tokenize = re.compile(r'(\d+)|(\D+)').findall 
def natural_sortkey(string):   
    return tuple(int(num) if num else alpha for num, alpha in tokenize(string)) 

sorted(my_set, key=natural_sortkey) 
3

यह सुझाव दिया गया है कि मैं यहाँ पर repost this answer के बाद से यह इस मामले भी

के लिए अच्छी तरह से काम करता है
from itertools import groupby 
def keyfunc(s): 
    return [int(''.join(g)) if k else ''.join(g) for k, g in groupby(s, str.isdigit)] 

sorted(my_list, key=keyfunc) 

डेमो:

>>> my_set = {'booklet', '4 sheets', '48 sheets', '12 sheets'} 
>>> sorted(my_set, key=keyfunc) 
['4 sheets', '12 sheets', '48 sheets', 'booklet'] 

python3 के लिए यह आवश्यक है यह थोड़ा बदलना चाहते हैं (इस संस्करण को Python2 में ठीक काम करता है भी)

def keyfunc(s): 
    return [int(''.join(g)) if k else ''.join(g) for k, g in groupby('\0'+s, str.isdigit)] 
1

अजगर का एक पूर्व 2.4 संस्करण के साथ फंस लोगों के लिए, अद्भुत sorted() फ़ंक्शन के बिना, सेट सॉर्ट करने का एक त्वरित तरीका है:

l = list(yourSet) 
l.sort() 

यह उपरोक्त विशिष्ट प्रश्न का उत्तर नहीं देता है (12 sheets4 sheets से पहले आएगा), लेकिन यह Google से आने वाले लोगों के लिए उपयोगी हो सकता है।

4

आपको तीसरे पक्ष की लाइब्रेरी natsort की जांच करनी चाहिए। इसका एल्गोरिदम सामान्य है इसलिए यह अधिकांश इनपुट के लिए काम करेगा।

>>> import natsort 
>>> your_list = set(['booklet', '4 sheets', '48 sheets', '12 sheets']) 
>>> print ',\n'.join(natsort.natsorted(your_list)) 
4 sheets, 
12 sheets, 
48 sheets, 
booklet 
0

तारों की सरणी में किसी भी स्थिति में किसी भी संख्या को क्रमबद्ध करने के लिए सामान्य उत्तर। अजगर के साथ काम करता 2 & 3.

def alphaNumOrder(string): 
    """ Returns all numbers on 5 digits to let sort the string with numeric order. 
    Ex: alphaNumOrder("a6b12.125") ==> "a00006b00012.00125" 
    """ 
    return ''.join([format(int(x), '05d') if x.isdigit() 
        else x for x in re.split(r'(\d+)', string)]) 

नमूना:

s = ['a10b20','a10b1','a3','b1b1','a06b03','a6b2','a6b2c10','a6b2c5'] 
s.sort(key=alphaNumOrder) 
s ===> ['a3', 'a6b2', 'a6b2c5', 'a6b2c10', 'a06b03', 'a10b1', 'a10b20', 'b1b1'] 

जवाब का एक हिस्सा is from there