2011-01-07 13 views
21

सबसे पहले, मैं इसे पोस्ट कर रहा हूं क्योंकि जब मैं नीचे की समस्या का हल ढूंढ रहा था, तो मुझे स्टैक ओवरफ्लो पर कोई नहीं मिला। तो, मैं यहां ज्ञान आधार पर थोड़ा सा जोड़ने की उम्मीद कर रहा हूं।आप संख्यात्मक रूप से फ़ाइलों को कैसे क्रमबद्ध करते हैं?

मुझे निर्देशिका में कुछ फ़ाइलों को संसाधित करने की आवश्यकता है और फ़ाइलों को संख्यात्मक रूप से क्रमबद्ध करने की आवश्यकता है। मैं छँटाई पर कुछ उदाहरण पाया - विशेष रूप से lambda पद्धति का उपयोग कर के साथ - wiki.python.org पर, और मैं एक साथ डाल:

#!env/python 
import re 

tiffFiles = """ayurveda_1.tif 
ayurveda_11.tif 
ayurveda_13.tif 
ayurveda_2.tif 
ayurveda_20.tif 
ayurveda_22.tif""".split('\n') 

numPattern = re.compile('_(\d{1,2})\.', re.IGNORECASE) 

tiffFiles.sort(cmp, key=lambda tFile: 
        int(numPattern.search(tFile).group(1))) 

print tiffFiles 

मैं अभी भी नहीं बल्कि अजगर करने के लिए नया हूँ और देखते हैं अगर समुदाय पूछना चाहूँगा इसमें कोई भी सुधार किया जा सकता है: कोड को छोटा करना (lambda हटा रहा है), प्रदर्शन, शैली/पठनीयता?

धन्यवाद, जाकारी

+2

+1। – systemovich

+4

आप जो कर रहे हैं, उसे करने के लिए _right_ तरीका सिर्फ प्रश्न बिट में प्रश्न पूछना है, फिर उत्तर में अपना उत्तर जोड़ें। फिर वापस बैठो और प्रतीक्षा करें ... – paxdiablo

+0

@paxdiablo: निर्देश के लिए धन्यवाद ... मैंने यह सुनिश्चित करने के लिए अक्सर पूछे जाने वाले प्रश्न पढ़े थे कि मैकेनिक्स के बारे में बिल्कुल यकीन नहीं था। मैं अगली बार इसे ठीक कर दूंगा। –

उत्तर

30

यह "प्राकृतिक छंटाई" या "मानव छंटाई" (के रूप में छँटाई lexicographical करने का विरोध किया है, जो डिफ़ॉल्ट है) कहा जाता है। Ned B wrote up a quick version of one.

import re 

def tryint(s): 
    try: 
     return int(s) 
    except: 
     return s 

def alphanum_key(s): 
    """ Turn a string into a list of string and number chunks. 
     "z23a" -> ["z", 23, "a"] 
    """ 
    return [ tryint(c) for c in re.split('([0-9]+)', s) ] 

def sort_nicely(l): 
    """ Sort the given list in the way that humans expect. 
    """ 
    l.sort(key=alphanum_key) 

यह आप क्या कर रहे हैं के समान है, लेकिन शायद थोड़ा अधिक सामान्यीकृत।

+1

धन्यवाद, डैनियल! ये वही है जिसे मैं ढूंढ रहा था। मैंने आपके द्वारा शामिल किए गए लिंक का पालन किया और खरगोश छेद नीचे चला गया ... weeee !!! मैंने कोशिश/छोड़ने के प्रदर्शन के बारे में थोड़ा सी सीखा, और (ज़ाहिर है) पूर्व-संकलन regexps। :) –

+0

क्या यह काम करेगा यदि हम एक सूची समझ के बजाय जनरेटर वापस करते हैं? –

+0

नकारात्मक एम्बेडेड संख्याओं को सही तरीके से संभाल नहीं करता है। – martineau

5

यदि आप अपनी सॉर्ट विधि में key= का उपयोग कर रहे हैं तो आपको cmp का उपयोग नहीं करना चाहिए जिसे पायथन के नवीनतम संस्करणों से हटा दिया गया है। key को उस फ़ंक्शन के बराबर होना चाहिए जो इनपुट के रूप में रिकॉर्ड लेता है और किसी भी ऑब्जेक्ट को देता है जो उस क्रम में तुलना करेगा जो आप अपनी सूची को सॉर्ट करना चाहते हैं। इसे लैम्ब्डा फ़ंक्शन होने की आवश्यकता नहीं है और स्टैंड स्टैंड अकेले फ़ंक्शन के रूप में स्पष्ट हो सकता है। मूल्यांकन के लिए भी नियमित अभिव्यक्ति धीमी हो सकती है।

आप की तरह कुछ की कोशिश कर सकते अलग करने और फ़ाइल नाम का पूर्णांक भाग वापस जाने के लिए निम्नलिखित:

टपल में
def getint(name): 
    basename = name.partition('.') 
    alpha, num = basename.split('_') 
    return int(num) 
tiffiles.sort(key=getint) 
+0

धन्यवाद, डॉन। मैं वास्तव में आपकी व्याख्या की सराहना करता हूं: बहुत समझ में आता है। --Zachary –

+0

@ डॉन ओ'डोनेल मुझे त्रुटि मिली _AttributeError: 'tuple' ऑब्जेक्ट में कोई विशेषता नहीं है 'split'_ इसलिए मैंने थोड़ा सा कोड संशोधित किया: ' बेसनाम = name.partition ('।') 'मैं ' basename = name.split ('।') '(** महत्वपूर्ण! केवल डॉट्स के बिना फ़ाइल नामों के लिए काम करता है **) और 'अल्फा, num = basename.split (' _ ')' अल्फा, num = basename [0] के साथ .split ('_') 'वैसे भी, आपने मेरा दिन बनाया है। धन्यवाद! – KnightWhoSayNi

0

विभाजन परिणाम

def getint(name): 
    (basename, part, ext) = name.partition('.') 
    (alpha, num) = basename.split('_') 
    return int(num) 
+0

क्या आप वास्तव में कोशिश करते थे? '(ए, बी, सी) = 'आयुर्वेद_11.tif'.split ('। '), ValueError: अनपॅक करने के लिए 2 से अधिक मानों की आवश्यकता है' –

5

बस का उपयोग करें:

tiffFiles.sort(key=lambda var:[int(x) if x.isdigit() else x for x in re.findall(r'[^0-9]|[0-9]+', var)]) 

उपयोग करने/छोड़ने के उपयोग से तेज़ है। एक उचित प्रश्न शीर्षक के लिए

संबंधित मुद्दे