ความเป็นไปได้สามประการ:
foo = """
this is 
a multi-line string.
"""
def f1(foo=foo): return iter(foo.splitlines())
def f2(foo=foo):
    retval = ''
    for char in foo:
        retval += char if not char == '\n' else ''
        if char == '\n':
            yield retval
            retval = ''
    if retval:
        yield retval
def f3(foo=foo):
    prevnl = -1
    while True:
      nextnl = foo.find('\n', prevnl + 1)
      if nextnl < 0: break
      yield foo[prevnl + 1:nextnl]
      prevnl = nextnl
if __name__ == '__main__':
  for f in f1, f2, f3:
    print list(f())
การรันสิ่งนี้เป็นสคริปต์หลักยืนยันว่าฟังก์ชันทั้งสามเทียบเท่ากัน ด้วยtimeit(และ* 100สำหรับfooเพื่อให้ได้สตริงจำนวนมากเพื่อการวัดที่แม่นยำยิ่งขึ้น):
$ python -mtimeit -s'import asp' 'list(asp.f3())'
1000 loops, best of 3: 370 usec per loop
$ python -mtimeit -s'import asp' 'list(asp.f2())'
1000 loops, best of 3: 1.36 msec per loop
$ python -mtimeit -s'import asp' 'list(asp.f1())'
10000 loops, best of 3: 61.5 usec per loop
โปรดทราบว่าเราต้องการการlist()โทรเพื่อให้แน่ใจว่าตัววนซ้ำถูกส่งผ่านไม่ใช่แค่สร้างขึ้น
IOW การใช้งานที่ไร้เดียงสานั้นเร็วกว่ามากมันไม่ตลกเลย: เร็วกว่าความพยายามในการfindโทรถึง 6 เท่าซึ่งเร็วกว่าวิธีการระดับล่างถึง 4 เท่า
บทเรียนที่ควรเก็บไว้: การวัดผลเป็นสิ่งที่ดีเสมอ (แต่ต้องแม่นยำ) วิธีการสตริงเช่นsplitlinesถูกนำไปใช้ในรูปแบบที่รวดเร็วมาก การวางสตริงเข้าด้วยกันโดยการเขียนโปรแกรมในระดับที่ต่ำมาก (โดยเฉพาะการวนซ้ำ+=ของชิ้นเล็ก ๆ ) อาจค่อนข้างช้า
แก้ไข : เพิ่มข้อเสนอของ @ Jacob ซึ่งแก้ไขเล็กน้อยเพื่อให้ได้ผลลัพธ์เช่นเดียวกับข้ออื่น ๆ (ช่องว่างต่อท้ายบรรทัดจะถูกเก็บไว้) เช่น:
from cStringIO import StringIO
def f4(foo=foo):
    stri = StringIO(foo)
    while True:
        nl = stri.readline()
        if nl != '':
            yield nl.strip('\n')
        else:
            raise StopIteration
การวัดให้:
$ python -mtimeit -s'import asp' 'list(asp.f4())'
1000 loops, best of 3: 406 usec per loop
ไม่ค่อยดีเท่า.findวิธีการตาม - แต่ก็ควรคำนึงถึงเพราะอาจมีแนวโน้มที่จะเกิดข้อบกพร่องเล็ก ๆ น้อย ๆ (ลูปใด ๆ ที่คุณเห็นการเกิดขึ้นของ +1 และ -1 เช่นเดียวกับf3ข้างต้นของฉันควรทำโดยอัตโนมัติ ทำให้เกิดความสงสัยแบบทีละรายการ - และควรมีลูปจำนวนมากที่ขาดการปรับแต่งดังกล่าวและควรมี - แม้ว่าฉันจะเชื่อว่ารหัสของฉันถูกต้องเนื่องจากฉันสามารถตรวจสอบเอาต์พุตด้วยฟังก์ชันอื่น ๆ ได้ ')
แต่แนวทางแบบแยกส่วนยังคงเป็นกฎเกณฑ์
กัน: สไตล์ที่ดีกว่าอาจf4จะเป็น:
from cStringIO import StringIO
def f4(foo=foo):
    stri = StringIO(foo)
    while True:
        nl = stri.readline()
        if nl == '': break
        yield nl.strip('\n')
อย่างน้อยก็น้อยลงเล็กน้อย ความจำเป็นในการตัดต่อท้าย\nเป็นสิ่งที่ห้ามการแทนที่whileลูปที่ชัดเจนและเร็วขึ้นด้วยreturn iter(stri)( iterส่วนที่ซ้ำซ้อนใน Python เวอร์ชันใหม่ฉันเชื่อว่าตั้งแต่ 2.3 หรือ 2.4 แต่ก็ไม่มีอันตรายเช่นกัน) อาจจะคุ้มค่าที่จะลอง:
    return itertools.imap(lambda s: s.strip('\n'), stri)
หรือรูปแบบต่างๆ - แต่ฉันกำลังหยุดอยู่ตรงนี้เพราะมันค่อนข้างเป็นการฝึกทางทฤษฎีที่ใช้stripพื้นฐานง่ายที่สุดและเร็วที่สุด
               
              
foo.splitlines()ใช่ไหม