2009-12-21 11 views
6

मैं अजगर 2.5 चल रहा हूँ (R25: 51,908 Sep 19, 2006, 09:52:17) [एमएससी v.1310 32 बिट (इंटेल)] जीत 32पायथन "u11-वाक्यांश 101.wav" से पहले "u11-वाक्यांश 101.wav"; मैं इससे कैसे उबरूं?

पर जब मैं अजगर

पूछ रहा हूँ
>>> "u11-Phrase 099.wav" < "u11-Phrase 1000.wav" 
True 

यह ठीक है। जब मैं

>>> "u11-Phrase 100.wav" < "u11-Phrase 1000.wav" 
True 

यह भी ठीक है। लेकिन जब मैं

>>> "u11-Phrase 101.wav" < "u11-Phrase 1000.wav" 
False 

पूछना तो अनुसार अजगर "यू 11-वाक्यांश 100.wav" पहले "यू 11-वाक्यांश 1000.wav" लेकिन "यू 11-वाक्यांश 101.wav" आता है के बाद "यू 11-वाक्यांश 1000 आता है .wav "! और यह मेरे लिए समस्याग्रस्त है क्योंकि मैं एक फ़ाइल नामकरण कार्यक्रम लिखने की कोशिश कर रहा हूं और इस प्रकार की सॉर्टिंग कार्यक्षमता को तोड़ देती है।

इस पर काबू पाने के लिए मैं क्या कर सकता हूं? क्या मुझे अपना स्वयं का सीएमपी फ़ंक्शन लिखना चाहिए और किनारे के मामलों के लिए परीक्षण करना चाहिए या क्या मुझे आदेश देने के लिए एक बहुत ही सरल शॉर्टकट है?

दूसरी ओर हालांकि उन तार जैसे निर्देशिका की फ़ाइल सूची से आते हैं अगर मैं इस तरह के

>>> "u11-Phrase 0101.wav" < "u11-Phrase 1000.wav" 
True 

के रूप में तार को संशोधित:

files = glob.glob('*.wav') 
files.sort() 
for file in files: 
    ... 

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

कोई संकेत?

उत्तर

16

आप human sorting की तलाश में हैं।

कारण 101.wav 1000.wav से कम नहीं है। कंप्यूटर यह है कि कंप्यूटर (केवल पायथन नहीं) चरित्र द्वारा तारों को क्रमबद्ध करते हैं, और इन दो तारों के बीच पहला अंतर है जहां पहली स्ट्रिंग में '1' होता है और दूसरी स्ट्रिंग में '0' है। '1' '0' से कम नहीं है, इसलिए तारों की तुलना आपने तुलना की है।

लोग स्वाभाविक रूप से उन तारों को अपने घटकों में पार्स करते हैं, और संख्यात्मक रूप से संख्याओं की व्याख्या करते हैं, न कि स्पष्ट रूप से। जो कोड मैंने ऊपर से जोड़ा है वह वही प्रकार का पार्सिंग करेगा।

+1

प्राकृतिक सॉर्टिंग भी कहा जाता है: http://www.codinghorror.com/blog/archives/001018.html –

+2

+1। कूल लिंक, मैं सिर्फ सवाल का जवाब देने वाला था। अब इसके लिए कोई ज़रूरत नहीं है। – Boldewyn

9

आपको प्रत्येक फ़ाइल नाम के लिए उचित सॉर्ट कुंजी बनाने की आवश्यकता है।

['u11-Phrase 099.wav', 'u11-Phrase 1000.wav', 'u11-Phrase 100.wav'] 
['u11-Phrase 099.wav', 'u11-Phrase 100.wav', 'u11-Phrase 1000.wav'] 

k समारोह अलग फ़ाइल नाम अंक के अनुक्रम के (अधिक महत्वपूर्ण) बंट जाएगा और पूर्णांकों में उन दृश्यों बारी:

import re 

def k(s): 
    return [w.isdigit() and int(w) or w for w in re.split(r'(\d+)', s)] 

files = ["u11-Phrase 099.wav", "u11-Phrase 1000.wav", "u11-Phrase 100.wav"] 

print files 
print sorted(files, key=k) 

यह इस उत्पादन देता है: कुछ इस तरह आप क्या चाहते हैं क्या करना चाहिए :

>>> k('u11-Phrase 099.wav') 
['u', 11, '-Phrase ', 99, '.wav'] 

हम तो तथ्य अजगर को पता है कि कैसे सूचियों सॉर्ट करने के लिए उपयोग करते हैं --- यह प्रत्येक तत्व एक के बाद एक की तुलना द्वारा सूचियों क्रमबद्ध करता है।अंतिम परिणाम है कि

>>> k('u11-Phrase 99.wav') < k('u11-Phrase 100.wav') 
True 

जबकि

>>> 'u11-Phrase 99.wav' < 'u11-Phrase 100.wav' 
False 

आप पहले से ही पता चला गया है के रूप में है।

+0

बहुत बहुत धन्यवाद। यह मैं क्या उम्मीद करता है और मैं हल कर (फाइलें, कुंजी = ट) में फ़ाइल के लिए की तरह उपयोग कर सकते हैं: प्रिंट फ़ाइल ... –

+0

मुझे आश्चर्य है कि क्या यह प्राकृतिक/मानव तरह आदेश कभी भी किसी भी मानक lib का हिस्सा होगा किसी भी प्रोग्रामिंग भाषा में ... –

+0

@Emre, शायद नहीं, क्योंकि आम तौर पर लागू होने वाली कुछ चीज़ों को ढूंढना बहुत मुश्किल होगा। उदाहरण के लिए, यह संभव है कि इनपुट के "u11" हिस्से को "यू" और पूर्णांक 11 के रूप में माना जाना चाहिए क्योंकि यह 3 वर्णों की एक साधारण स्ट्रिंग के रूप में माना जाना चाहिए। आमतौर पर यह पूरी तरह से संदर्भ संवेदनशील है। और पाइथन में, कम से कम, एक कस्टम सॉर्ट कुंजी फ़ंक्शन लिखना एक मानक लाइब्रेरी दिनचर्या बनाने के लिए परेशान करना बहुत आसान है। –

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