विभाजित () परिणामों में खाली तार क्यों लौटाए जाते हैं?


120

'/segment/segment/'.split('/')लौटने की बात क्या है ['', 'segment', 'segment', '']?

खाली तत्वों को नोटिस करें। यदि आप एक सीमांकक पर विभाजित कर रहे हैं जो एक स्थिति पर और एक स्ट्रिंग के बहुत अंत में होता है, तो प्रत्येक छोर से खाली स्ट्रिंग वापस करने के लिए आपको क्या अतिरिक्त मूल्य देता है?


1
मेरे पास एक ही सवाल है और इसे लंबे समय तक खोजा। अब मैं समझता हूं कि खाली परिणाम वास्तव में महत्वपूर्ण हैं। आपके प्रश्न के लिए धन्यवाद।
पन्नाधाय

2
strip()बंटवारे से पहले स्ट्रिंग से स्प्लिट '/segment/segment/'.strip('/').split('/')
लीड्स

जवाबों:


178

str.splitपूरक str.join, तो

"/".join(['', 'segment', 'segment', ''])

आपको मूल स्ट्रिंग वापस मिलती है।

यदि खाली तार नहीं थे, तो पहले और आखिरी के '/'बाद गायब हो जाएगाjoin()


11
सरल, लेकिन पूरी तरह से सवाल का जवाब देता है।
orokusaki

मुझे यह जानकर झटका लगा कि वास्तव में पायथन में घुंघराले उद्धरण मान्य हैं ... लेकिन, लेकिन ... कैसे? डॉक्स इसका उल्लेख नहीं करते हैं।
टिम पीटरज़्ट

@ टिम, मुझे नहीं पता कि उन उद्धरणों को वहां कैसे मिला: /
जॉन ला रोयॉय

7
तो, आप अपने Python IDE के रूप में Microsoft Word का उपयोग नहीं कर रहे हैं, तब? :)
टिम Pietzcker

1
@ aaa90210 ने कहा कि सरल उत्तर सर्वश्रेष्ठ नहीं थे? यह एक टिप्पणी थी (सबसे पहले, 5 साल पहले) इसका जवाब कैसे सरल था, लेकिन इस सवाल का पूरी तरह से जवाब दिया। एक वाक्य में "लेकिन" का उपयोग करने से कुछ बुरा नहीं होता है। एक गैर-सरल उत्तर एक अधिक पूर्ण उत्तर हो सकता है (उदाहरण के लिए, प्रासंगिक निर्णयों या विख्यात कार्यक्षमता से संबंधित पीईपी सहित)।
ओरोकुसाकी

88

आम तौर पर, split()परिणामों में लौटे खाली तारों को हटाने के लिए , आप देखना चाह सकते हैंfilter फ़ंक्शन ।

उदाहरण:

filter(None, '/segment/segment/'.split('/'))

रिटर्न

['segment', 'segment']

3
इसके लिए धन्यवाद, मुझे नहीं पता कि यह उत्तर इतना नीचे क्यों है, बाकी सब कुछ अल्पविकसित सामान है।
वेज

6
यदि आउटपुट के रूप में फ़िल्टर ऑब्जेक्ट प्राप्त करने के बजाय किसी सूची में परिणाम एकत्र करना वांछित है, तो संपूर्ण फ़िल्टर संरचना को अंदर रखें list(...)
बजे टिम विज़े

29

यहाँ पर विचार करने के लिए दो मुख्य बिंदु हैं:

  • परिणाम के '/segment/segment/'.split('/')बराबर होने की उम्मीद करना ['segment', 'segment']उचित है, लेकिन फिर यह जानकारी खो देता है। यदि split()आप चाहते हैं कि जिस तरह से काम किया है, अगर मैं आपको बताता हूं कि a.split('/') == ['segment', 'segment'], आप मुझे नहीं बता सकते कि क्या aथा।
  • परिणाम क्या होना 'a//b'.split()चाहिए? ['a', 'b']? या ['a', '', 'b']? यानी, split()आसन्न सीमांकक का विलय करना चाहिए ? यदि यह होना चाहिए, तो एक चरित्र द्वारा सीमांकित डेटा को पार्स करना बहुत कठिन होगा, और कुछ फ़ील्ड खाली हो सकते हैं। मुझे यकीन है कि वहाँ कई लोग हैं जो कर रहे हैं काफी हूँ कर उपरोक्त मामले के लिए परिणाम में खाली मान चाहते हैं!

अंत में, यह दो चीजों को उबालता है:

संगति: यदि मेरे पास nसीमांकक है, तो a, मुझे n+1मान वापस मिलता हैsplit()

जटिल चीजों को करना संभव है, और सरल चीजों को करना आसान है: यदि आप इसके परिणामस्वरूप खाली तारों को अनदेखा करना चाहते हैं split(), तो आप हमेशा ऐसा कर सकते हैं:

def mysplit(s, delim=None):
    return [x for x in s.split(delim) if x]

लेकिन अगर कोई खाली मूल्यों को नजरअंदाज नहीं करना चाहता है, तो उसे करना चाहिए उसे सक्षम ।

भाषा की एक-एक परिभाषा split()चुननी होती है- डिफ़ॉल्ट के रूप में हर किसी की आवश्यकता को पूरा करने के लिए कई अलग-अलग उपयोग के मामले हैं। मुझे लगता है कि पायथन की पसंद एक अच्छी है, और सबसे तार्किक है। (एक तरफ के रूप में, एक कारण मुझे C पसंद नहीं हैstrtok() है क्योंकि यह आसन्न सीमांकक को विलीन कर देता है, जिससे इसके साथ गंभीर पार्सिंग / टोकन करना बहुत कठिन हो जाता है।)

एक अपवाद है: a.split()एक तर्क के बिना लगातार सफेद-स्थान को निचोड़ता है, लेकिन कोई यह तर्क दे सकता है कि उस मामले में ऐसा करना सही है। यदि आप व्यवहार नहीं चाहते हैं, तो आप हमेशा कर सकते हैं a.split(' ')


उन लोगों के लिए जो डुप्लिकेट स्थानों को न्यूक करने के लिए तेज़ हैं, फिर विभाजित होते हैं, या विभाजित होते हैं और केवल गैर-रिक्त स्ट्रिंग्स लेते हैं, यहाँ मुझे क्या मिलता है: python3 -m timeit "import re ; re.sub(' +', ' foo bar baz ', '').split(' ')"-> 875 nsec प्रति लूप; python3 -m timeit "[token for token in ' foo bar baz '.split(' ') if token]"-> 616 nsec प्रति लूप
s3cur3

8

बीत रहा है x.split(y)हमेशा की एक सूची प्रदान 1 + x.count(y)आइटम एक कीमती नियमितता है - के रूप में @ gnibbler पहले से ही बताया है बाहर यह बनाता है splitऔर joinएक दूसरे के सटीक प्रतिलोम (के रूप में वे स्पष्ट रूप से होना चाहिए), यह भी ठीक सीमांकक-में शामिल हो गए रिकॉर्ड के सभी प्रकार के अर्थ विज्ञान (नक्शे जैसे csvफ़ाइल लाइनें [[मुद्दों को उद्धृत करने का जाल]], से लाइनें/etc/group यूनिक्स में और इसी तरह), यह अनुमति देता है (जैसा कि @ रोमन के उत्तर का उल्लेख है) (जैसे) पूर्ण बनाम सापेक्ष पथ (फ़ाइल पथ और URL में) के लिए आसान चेक, इत्यादि।

इसे देखने का एक और तरीका यह है कि आप बिना किसी लाभ के लिए विंडो से बाहर जानकारी नहीं चाहते हैं। के x.split(y)बराबर बनाने में क्या हासिल होगा x.strip(y).split(y)? कुछ भी नहीं है, निश्चित रूप से - यह आसान दूसरा फार्म का उपयोग करने के लिए है कि मान लीजिए कि आप क्या मतलब है, लेकिन अगर पहला रूप मनमाने ढंग से एक दूसरे मतलब समझा रहा था, आप काम का बहुत कुछ है जब आप चाहते हैं जब करते हैं पहले एक चाहते हैं ( जो कि पिछले पैराग्राफ को इंगित करता है) से बहुत दूर है।

लेकिन वास्तव में, गणितीय नियमितता के संदर्भ में सोचना सबसे सरल और सबसे सामान्य तरीका है जिससे आप खुद को निष्क्रिय एपीआई डिजाइन करना सिखा सकते हैं। एक अलग उदाहरण लेने के लिए, यह बहुत महत्वपूर्ण है कि किसी भी वैध के लिए xऔर y x == x[:y] + x[y:]- जो तुरंत इंगित करता है कि क्यों एक स्लाइसिंग के एक चरम को बाहर रखा जाना चाहिए। आपके द्वारा तैयार किए जाने वाले अपरिवर्तनीय दावे को जितना सरल बनाया जा सकता है, उतना ही अच्छा लगता है कि परिणामी शब्दार्थ वे होते हैं जिनकी आपको वास्तविक जीवन में उपयोग करने की आवश्यकता होती है - रहस्यमय तथ्य का हिस्सा है कि गणित ब्रह्मांड से निपटने में बहुत उपयोगी है।

एक splitबोली के लिए इनवेरिएंट तैयार करने का प्रयास करें जिसमें प्रमुख और अनुगामी सीमांकक विशेष आवरण वाले होते हैं ... काउंटर-उदाहरण: स्ट्रिंग विधियाँ जैसे कि isspaceअधिकतम सरल नहीं हैं - x.isspace()इसके बराबर है x and all(c in string.whitespace for c in x)- यह मूर्खतापूर्ण अग्रणी x andहै इसलिए आप अक्सर इसे कोडिंग पाते हैं not x or x.isspace()सादगी जो करने के लिए वापस पाने के लिए करना चाहिए में डिजाइन किया गया है is...(स्ट्रिंग तरीकों जिससे एक खाली स्ट्रिंग "है" कुछ भी आप चाहते हैं - मैन-इन-गली से घोड़े की भावना, हो सकता है [[खाली सेट के विपरीत, शून्य की तरह और सी, हमेशा ज्यादातर लोगों ;-)]], लेकिन पूरी तरह से स्पष्ट अच्छी तरह से परिष्कृत के अनुरूप भ्रमित हो गणितीय ! सामान्य व्यावहारिक -)।


5

मुझे यकीन नहीं है कि आप किस तरह के उत्तर की तलाश कर रहे हैं? आपको तीन मैच मिलते हैं क्योंकि आपके पास तीन सीमांकक हैं। यदि आप उस खाली को नहीं चाहते हैं, तो बस उपयोग करें:

'/segment/segment/'.strip('/').split('/')

4
-1 क्योंकि आपको चार मैच मिलते हैं तीन नहीं, और यह भी वास्तव में सवाल का जवाब नहीं देता है।
रोमन

1
+1 नकारात्मक का प्रतिकार करने के लिए .. उसने यह नहीं कहा कि आपको तीन परिणाम वापस मिलेंगे। उन्होंने "तीन सीमांकक" के लिए "तीन मैच" कहा, जो मेरे लिए तर्कसंगत लगता है। हालाँकि, आपको किसी भी चीज़ के "चार मैच" नहीं मिलते हैं। आपको अपने परिणाम में "चार तत्व" मिलते हैं, हालाँकि। इसके अलावा, यह सीधे "क्यों" का जवाब नहीं देता है, लेकिन यह एक सरल तरीका प्रदान करता है कि वह वास्तव में क्या चाहता है ... जो कि मुझे नहीं लगता कि एक पतन का हकदार है। यदि आप किसी को नीच (नीच के साथ, कोई कम नहीं) करने जा रहे हैं तो कृपया अधिक सावधान रहें! चीयर्स! 8 ^)
क्रोडब्रोन

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

मुझे आपके समाधान से प्यार है - पट्टी फिर खाली परिणाम निकालने के लिए अलग हो गई
नाम जी VU

5

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

सरल उदाहरण: कहते हैं कि आप पूर्ण बनाम सापेक्ष फ़ाइलनामों की जांच करना चाहते हैं। इस तरह आप यह सब विभाजन के साथ कर सकते हैं, बिना यह भी जांचे कि आपके फ़ाइलनाम का पहला चरित्र क्या है।


1

इस न्यूनतम उदाहरण पर विचार करें:

>>> '/'.split('/')
['', '']

splitआपको सीमांकक से पहले और बाद में क्या देना चाहिए '/', लेकिन कोई अन्य वर्ण नहीं है। तो यह है कि आप रिक्त स्ट्रिंग है, जो तकनीकी रूप से पहले आता है और इस प्रकार देने के लिए '/'है, क्योंकि '' + '/' + '' == '/'

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.