এখানে তিনটি সম্ভাবনা রয়েছে:
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()
ডানদিকে পুনরাবৃত্তি করতে পারেন ?