এখানে তিনটি সম্ভাবনা রয়েছে:
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(), কেবল নির্মিত না, পুনরাবৃত্তিগুলি ট্র্যাভারেজ করা হয়েছে তা নিশ্চিত করার জন্য আমাদের কল প্রয়োজন we
IOW, নিষ্পাপ বাস্তবায়ন এত তাড়াতাড়ি এটি মজাদারও নয়: findকলগুলির সাথে আমার প্রচেষ্টার চেয়ে 6 গুণ বেশি দ্রুতগতি হয় যা নিম্ন স্তরের পদ্ধতির চেয়ে 4 গুণ দ্রুত হয়।
রাখার পাঠ: পরিমাপ সর্বদা একটি ভাল জিনিস (তবে অবশ্যই সঠিক হতে হবে); স্ট্রিং পদ্ধতিগুলি splitlinesখুব দ্রুত উপায়ে প্রয়োগ করা হয়; খুব নিম্ন স্তরে প্রোগ্রামিংয়ের মাধ্যমে স্ট্রিংগুলি একসাথে স্থাপন করা (উদাহরণস্বরূপ লুপগুলি দ্বারা)+= , খুব ছোট টুকরোগুলির ) বেশ ধীর হতে পারে।
সম্পাদনা : যোগ করা @ জ্যাকবের প্রস্তাব, অন্যের মতো একই ফলাফল দেওয়ার জন্য কিছুটা সংশোধন করা (একটি লাইনে ফাঁকা ফাঁকা রাখা হয়), অর্থাত:
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ভিত্তিক পদ্ধতির মতো ততটা ভাল নয় - তবুও, মাথায় রাখার মতো কারণ এটি ছোট অফ-ওয়ান বাগের চেয়ে কম ঝুঁকিপূর্ণ হতে পারে (আমার f3উপরের মতো +1 এবং -1 এর উপস্থিতিগুলি দেখতে কোনও লুপটি স্বয়ংক্রিয়ভাবে হওয়া উচিত) একের পর এক সন্দেহের সূত্রপাত - এবং এমন অনেক লুপের উচিত যা এই জাতীয় টুইটগুলির অভাব রয়েছে এবং সেগুলি থাকা উচিত - যদিও আমি বিশ্বাস করি যে আমার কোডটিও ঠিক আছে যেহেতু আমি অন্যান্য ফাংশনগুলির সাথে এর ফলাফল আউট পরীক্ষা করতে সক্ষম হয়েছি)।
তবে বিভক্ত-ভিত্তিক পদ্ধতির এখনও নিয়ম রয়েছে।
একদিকে: সম্ভবত এর চেয়ে ভাল স্টাইলটি হ'ল f4:
from cStringIO import StringIO
def f4(foo=foo):
stri = StringIO(foo)
while True:
nl = stri.readline()
if nl == '': break
yield nl.strip('\n')
কমপক্ষে, এটি কিছুটা কম ভার্বোস। Trailing স্ট্রিপ প্রয়োজন \nগুলি দুর্ভাগ্যবশত এর পরিষ্কার এবং দ্রুত প্রতিস্থাপন নিষিদ্ধ whileসঙ্গে লুপ return iter(stri)( iterঅংশ কিসের পাইথন আধুনিক সংস্করণে অপ্রয়োজনীয় হয়, আমি বিশ্বাস করি 2.3 বা 2.4 থেকে, কিন্তু এটি নির্দোষ এর)। চেষ্টা করার মতোও হতে পারে:
return itertools.imap(lambda s: s.strip('\n'), stri)
বা এর বৈচিত্রগুলি - তবে আমি এখানে থেমে যাচ্ছি কারণ এটি একটি তাত্ত্বিক অনুশীলনের stripউপর ভিত্তি করে, সবচেয়ে সহজ এবং দ্রুততম, সবচেয়ে কার্যকর t
foo.splitlines()ডানদিকে পুনরাবৃত্তি করতে পারেন ?