मैं एक मल्टी-लाइन स्ट्रिंग को कई लाइनों में कैसे विभाजित करूं?


287

मेरे पास एक बहु-पंक्ति स्ट्रिंग शाब्दिक है जिसे मैं प्रत्येक पंक्ति पर एक ऑपरेशन करना चाहता हूं, जैसे:

inputString = """Line 1
Line 2
Line 3"""

मैं निम्नलिखित की तरह कुछ करना चाहता हूँ:

for line in inputString:
    doStuff()

जवाबों:


437
inputString.splitlines()

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


12
+1। मुझे लगता है कि यह स्वीकृत समाधान की तुलना में अच्छा है क्योंकि यह स्पष्ट रूप से लाइन विभाजक के साथ गड़बड़ नहीं करता है। यह सब सिर्फ एक समर्पित एपीआई विधि के साथ काम करता है!
lpapp

12
@ llapp, मैं पूरी तरह से सहमत हूँ। स्प्लिटलाइन () शब्दार्थ है (और कार्यात्मक रूप से, क्योंकि यह सार्वभौमिक न्यूलाइन्स का उपयोग करता है और एक अनुगामी खाली लाइन को छोड़ देता है) स्प्लिट ('\ n') से बेहतर है। तब (2008) मैं सिर्फ एक नौसिखिया पाइथोनिस्टा और ग्रेपिंग था, हालांकि अब मेरी लिपियों से पता चलता है कि मैं भी लगभग विशेष रूप से स्प्लिटलाइन () का उपयोग कर रहा हूं। इसलिए मैं अपने 104-पॉइंट उत्तर ( * sob ... * ) को हटा रहा हूं और इसके बजाय यह समर्थन करूंगा।
efotinis

18
यह भी बनाता है ''.splitlines() == [], ['']साथ नहीं ''.split('\n')
9

198

दूसरों ने कहा:

inputString.split('\n')  # --> ['Line 1', 'Line 2', 'Line 3']

यह उपरोक्त के समान है, लेकिन स्ट्रिंग मॉड्यूल के कार्यों को हटा दिया गया है और इसे टाला जाना चाहिए:

import string
string.split(inputString, '\n')  # --> ['Line 1', 'Line 2', 'Line 3']

वैकल्पिक रूप से, यदि आप ब्रेक अनुक्रम (सीआर, एलएफ, सीआरएलएफ) को शामिल करने के लिए प्रत्येक पंक्ति चाहते हैं, तो splitlinesएक Trueतर्क के साथ विधि का उपयोग करें :

inputString.splitlines(True)  # --> ['Line 1\n', 'Line 2\n', 'Line 3']

12
यह केवल उन सिस्टम पर काम करेगा जो लाइन टर्मिनेटर के रूप में '\ n' का उपयोग करते हैं।
जेरेमी कैंटरेल

20
@ जेरेमी: ट्रिपल-उद्धृत स्ट्रिंग शाब्दिक हमेशा प्लेटफ़ॉर्म की परवाह किए बिना एक '\ n' ईओएल का उपयोग करते हैं। तो क्या पाठ मोड में पढ़ी जाने वाली फाइलें।
efotinis

16
inputString.split(os.linesep)प्लेटफ़ॉर्म विशिष्ट लाइन टर्मिनेटर का उपयोग करेगा।
जेम्स

10
यह अजीब है कि यह उत्तर इतना उलझा हुआ है। हार्ड कोडिंग '\ n' एक बुरा विचार है, लेकिन फिर भी यदि आप इसके बजाय os.linesep का उपयोग करते हैं, तो आपके पास लिनक्स पर विंडो लाइन समाप्त होने और इसके विपरीत, आदि मुद्दे होंगे, इसके अलावा, यह ट्रूलाइन को ट्रू तर्क के साथ बढ़ावा दे रहा है जो है संभावना है कि इसे इस्तेमाल करने का कम सामान्य तरीका ...
lpapp

4
एक सबऑप्टिमल विधि का संयोजन, एक पदावनत विधि, और इष्टतम विधि का एक निरर्थक रूपांतर।
jwg

50

का उपयोग करेंstr.splitlines()

splitlines()इसके विपरीत, ठीक से नए सिरे से संभालता है split("\n")

इसमें वैकल्पिक रूप से @efotinis द्वारा उल्लिखित लाभ भी शामिल है, जब Trueतर्क के साथ विभाजित परिणाम में न्यूलाइन वर्ण शामिल होता है।


आप का उपयोग क्यों नहीं करना चाहिए पर विस्तृत विवरण split("\n"):

\nपायथन में, उस मंच से स्वतंत्र रूप से एक यूनिक्स लाइन-ब्रेक (ASCII दशमलव कोड 10) का प्रतिनिधित्व करता है, जहां आप इसे चलाते हैं। हालाँकि, लाइनब्रेक प्रतिनिधित्व प्लेटफ़ॉर्म-निर्भर है । विंडोज पर, \nदो वर्ण हैं, CRऔर LF(ASCII दशमलव कोड 13 और 10, AKA ) \rऔर \nकिसी भी आधुनिक यूनिक्स (OS X सहित) पर, यह एकल वर्ण है LF

print, उदाहरण के लिए, सही ढंग से काम करता है, भले ही आपके पास लाइन एंडिंग के साथ एक स्ट्रिंग हो जो आपके प्लेटफॉर्म से मेल न खाती हो:

>>> print " a \n b \r\n c "
 a 
 b 
 c

हालांकि, स्पष्ट रूप से "\ n" पर विभाजित होने से, प्लेटफ़ॉर्म-निर्भर व्यवहार प्राप्त होगा:

>>> " a \n b \r\n c ".split("\n")
[' a ', ' b \r', ' c ']

यहां तक ​​कि अगर आप उपयोग करते हैं os.linesep, तो यह केवल आपके प्लेटफ़ॉर्म पर नएलाइन विभाजक के अनुसार विभाजित होगा, और विफल हो जाएगा यदि आप अन्य प्लेटफार्मों में बनाए गए पाठ को संसाधित कर रहे हैं, या नंगे के साथ \n:

>>> " a \n b \r\n c ".split(os.linesep)
[' a \n b ', ' c ']

splitlines इन सभी समस्याओं का हल:

>>> " a \n b \r\n c ".splitlines()
[' a ', ' b ', ' c ']

पाठ मोड में फाइलें पढ़ना आंशिक रूप से न्यूलाइन प्रतिनिधित्व समस्या को कम करता है, क्योंकि यह पायथन \nको प्लेटफॉर्म की न्यूलाइन प्रतिनिधित्व में परिवर्तित करता है। हालाँकि, टेक्स्ट मोड केवल विंडोज पर मौजूद है। यूनिक्स प्रणालियों पर, सभी फाइलें बाइनरी मोड में खोली जाती हैं, इसलिए split('\n')एक यूनिक्स सिस्टम में विंडोज फाइल के साथ उपयोग करने से अवांछित व्यवहार हो जाएगा। इसके अलावा, अन्य स्रोतों, जैसे सॉकेट से संभावित रूप से अलग-अलग नईलाइनों के साथ तार को संसाधित करना असामान्य नहीं है।


तुलना उचित नहीं है क्योंकि आप प्लेटफ़ॉर्म विशिष्ट बिट से बचने के लिए विभाजन (os.linesep) का भी उपयोग कर सकते हैं।
lpapp

6
@ llapp नोट जो समाप्त होने वाली किसी भी रेखा splitlinesपर विभाजित हो जाएगा । यूनिक्स में एक विंडोज़ फ़ाइल पढ़ते समय असफल हो जाएगा, उदाहरण के लिएsplit(os.linesep)
goncalopp

1
मेरे मामले में स्प्लिटलाइन का उपयोग करने का एक और कारण, धन्यवाद। मैंने एक +1 दिया। मैं व्यक्तिगत रूप से टिप्पणियों में जानकारी को आपके उत्तर में शामिल करूंगा।
lpapp

20

इस विशेष मामले में ओवरकिल हो सकता है लेकिन StringIOफ़ाइल जैसी वस्तु बनाने के लिए एक अन्य विकल्प का उपयोग करना शामिल है

for line in StringIO.StringIO(inputString):
    doStuff()

हां, यह सबसे मुहावरेदार, सबसे पायथन-आईसी दृष्टिकोण है।
पैरामैग्नेटिक क्रोइसैंट

4
इस पद्धति का लाभ, जब तुलना की जाती है str.split, तो किसी भी मेमोरी को आवंटित करने की आवश्यकता नहीं होती है (यह स्ट्रिंग को इन-प्लेस पढ़ता है)। एक नुकसान यह है कि यह बहुत धीमी है अगर आपStringIO (लगभग 50x) का उपयोग करते हैं । यदि आप उपयोग करते हैं cStringIO, हालांकि, यह 2x के बारे में तेज है
goncalopp

2x तेजी से क्या?
इरिना रापोपोर्ट

1
@IrinaRapoport, cStringIO, Stringio की तुलना में 2x तेज है
iruvar

1

मूल पोस्ट कोड के लिए अनुरोध किया गया है जो कुछ पंक्तियों को प्रिंट करता है (यदि वे कुछ शर्त के लिए सही हैं) प्लस निम्न पंक्ति। मेरा कार्यान्वयन यह होगा:

text = """1 sfasdf
asdfasdf
2 sfasdf
asdfgadfg
1 asfasdf
sdfasdgf
"""

text = text.splitlines()
rows_to_print = {}

for line in range(len(text)):
    if text[line][0] == '1':
        rows_to_print = rows_to_print | {line, line + 1}

rows_to_print = sorted(list(rows_to_print))

for i in rows_to_print:
    print(text[i])

0

मैं चाहता हूं कि टिप्पणियों में उचित कोड टेक्स्ट फ़ॉर्मेटिंग हो, क्योंकि मुझे लगता है कि @ 1_CR के उत्तर को अधिक धक्कों की आवश्यकता है, और मैं उनके उत्तर को बढ़ाना चाहूंगा। वैसे भी, उन्होंने मुझे निम्नलिखित तकनीक तक पहुंचाया; यह उपलब्ध होने पर cStringIO का उपयोग करेगा (लेकिन ध्यान दें: cStringIO और StringIO समान नहीं हैं , क्योंकि आप cStringIO को उप-वर्ग नहीं कर सकते हैं ... यह एक अंतर्निहित है ... लेकिन बुनियादी संचालन के लिए वाक्यविन्यास समान होगा, इसलिए आप ऐसा कर सकते हैं। ):

try:
    import cStringIO
    StringIO = cStringIO
except ImportError:
    import StringIO

for line in StringIO.StringIO(variable_with_multiline_string):
    pass
print line.strip()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.