আপনি কীভাবে itertools
রেসিপিগুলি একত্রিত করতে পারেন তা দেখানোর জন্য , আমি pairwise
রেসিপিটি যতটা সম্ভব সম্ভব window
রেসিপিটি ব্যবহার করে consume
রেসিপিটি প্রসারিত করছি :
def consume(iterator, n):
"Advance the iterator n-steps ahead. If n is none, consume entirely."
# Use functions that consume iterators at C speed.
if n is None:
# feed the entire iterator into a zero-length deque
collections.deque(iterator, maxlen=0)
else:
# advance to the empty slice starting at position n
next(islice(iterator, n, n), None)
def window(iterable, n=2):
"s -> (s0, ...,s(n-1)), (s1, ...,sn), (s2, ..., s(n+1)), ..."
iters = tee(iterable, n)
# Could use enumerate(islice(iters, 1, None), 1) to avoid consume(it, 0), but that's
# slower for larger window sizes, while saving only small fixed "noop" cost
for i, it in enumerate(iters):
consume(it, i)
return zip(*iters)
window
রেসিপি জন্য হিসাবে একই pairwise
, এটা ঠিক একক উপাদান "গ্রাস" দ্বিতীয় প্রতিস্থাপন tee
কার্যক্রমে উপর হ্রাস বৃদ্ধি সঙ্গে -ed পুনরুক্তিকারীর n - 1
iterators। consume
প্রতিটি আয়রেটরকে মোড়ানোর পরিবর্তে ব্যবহার করা islice
প্রান্তিকভাবে দ্রুত (যথেষ্ট পরিমাণে বৃহত পুনরাবৃত্তির জন্য) যেহেতু আপনি কেবল পর্বের islice
সময় মোড়কের ওভারহেড প্রদান করেন consume
, প্রতিটি উইন্ডো-এডিড মান বের করার প্রক্রিয়া চলাকালীন নয় (যাতে এটি আবদ্ধ হয় n
, আইটেমের সংখ্যা নয়) iterable
)।
পারফরম্যান্স-ভিত্তিক, অন্য কয়েকটি সমাধানের তুলনায়, এটি বেশ ভাল (এবং এটির আঁশ হিসাবে পরীক্ষিত অন্যান্য সমাধানগুলির চেয়ে ভাল)। ipython
%timeit
ম্যাজিক ব্যবহার করে পাইথন 3.5.0.0, লিনাক্স x86-64 এ পরীক্ষিত ।
কিন্ডাল এর deque
সমাধান , islice
হোম-রোলড জেনারেটর এক্সপ্রেশন পরিবর্তে ব্যবহার করে ফলাফলের দৈর্ঘ্য পরীক্ষা করে পারফরম্যান্স / নির্ভুলতার জন্য টুইট করা হয়েছে যাতে উইন্ডোটির চেয়ে বারে বারে ছোট হওয়ার maxlen
সাথে সাথে deque
অবস্থানের পরিবর্তে স্থায়ীভাবে পাস করার ফলে ফল পাওয়া যায় না well কীওয়ার্ড দ্বারা (ছোট ইনপুটগুলির জন্য একটি আশ্চর্যজনক পার্থক্য তৈরি করে):
>>> %timeit -r5 deque(windowkindall(range(10), 3), 0)
100000 loops, best of 5: 1.87 μs per loop
>>> %timeit -r5 deque(windowkindall(range(1000), 3), 0)
10000 loops, best of 5: 72.6 μs per loop
>>> %timeit -r5 deque(windowkindall(range(1000), 30), 0)
1000 loops, best of 5: 71.6 μs per loop
পূর্ববর্তী অভিযোজিত কিন্ডাল সমাধান হিসাবে একই, তবে প্রতিটি yield win
পরিবর্তিত হয়ে yield tuple(win)
জেনারেটর থেকে প্রাপ্ত ফলাফলগুলি সংরক্ষণের পরিবর্তে সমস্ত সঞ্চিত ফলাফল ব্যতীত সর্বাধিক সাম্প্রতিক ফলাফলের দৃষ্টিভঙ্গি না হয়ে কাজ করে (অন্যান্য সমস্ত যুক্তিসঙ্গত সমাধান এই দৃশ্যে নিরাপদ), এবং tuple=tuple
ফাংশন সংজ্ঞায় যুক্ত করে ব্যবহারের সরাতে tuple
থেকে B
এ LEGB
থেকে L
:
>>> %timeit -r5 deque(windowkindalltupled(range(10), 3), 0)
100000 loops, best of 5: 3.05 μs per loop
>>> %timeit -r5 deque(windowkindalltupled(range(1000), 3), 0)
10000 loops, best of 5: 207 μs per loop
>>> %timeit -r5 deque(windowkindalltupled(range(1000), 30), 0)
1000 loops, best of 5: 348 μs per loop
consume
ভিত্তিক সমাধান উপরে দেখানো হয়েছে:
>>> %timeit -r5 deque(windowconsume(range(10), 3), 0)
100000 loops, best of 5: 3.92 μs per loop
>>> %timeit -r5 deque(windowconsume(range(1000), 3), 0)
10000 loops, best of 5: 42.8 μs per loop
>>> %timeit -r5 deque(windowconsume(range(1000), 30), 0)
1000 loops, best of 5: 232 μs per loop
একই consume
, তবে রানটাইম হ্রাস করার জন্য ফাংশন কল এবং পরীক্ষা এড়ানোর else
ক্ষেত্রে অন্তর্নিহিত ক্ষেত্রে , বিশেষত ছোট ইনপুটগুলির ক্ষেত্রে যেখানে সেটআপ ওভারহেড কাজের অর্থপূর্ণ অংশ:consume
n is None
>>> %timeit -r5 deque(windowinlineconsume(range(10), 3), 0)
100000 loops, best of 5: 3.57 μs per loop
>>> %timeit -r5 deque(windowinlineconsume(range(1000), 3), 0)
10000 loops, best of 5: 40.9 μs per loop
>>> %timeit -r5 deque(windowinlineconsume(range(1000), 30), 0)
1000 loops, best of 5: 211 μs per loop
(পার্শ্ব-নোট: এটির একটি বৈকল্পিক নেস্টেড অবজেক্টগুলি তৈরি করতে বার বার 2 টির ডিফল্ট যুক্তি pairwise
ব্যবহার করে, তাই প্রদত্ত যে কোনও tee
পুনরাবৃত্তিকে tee
কেবল একবার উন্নত করা হয়, স্বতঃস্ফূর্তভাবে ক্রমবর্ধমান সংখ্যক বার গ্রাস করা হয় না, মিঃডিআরফেনারের উত্তরটির অনুরূপ অন- ইনলাইনডের অনুরূপ) consume
এবং consume
সমস্ত পরীক্ষার অন্তর্ভুক্তের চেয়ে ধীর গতির , তাই আমি বংশবৃদ্ধির জন্য ফলাফলগুলি বাদ দিয়েছি)।
যেমন আপনি দেখতে পাচ্ছেন, যদি আপনি কলারের ফলাফল সংরক্ষণের প্রয়োজনীয়তার বিষয়ে চিন্তা না করেন তবে কান্ডাল এর সমাধানের আমার অনুকূলিত সংস্করণটি বেশিরভাগ সময় "consume
বিজয়ী , ছোট উইন্ডো আকারের কেস" ব্যতীত জিতবে (যেখানে ইনলাইনড জেতা ); এটি পুনরাবৃত্ত আকারে বাড়ার সাথে সাথে তা দ্রুত হ্রাস পায়, উইন্ডোর আকার বাড়ার সাথে সাথে একেবারে অবনতি হয় না (প্রতিটি অন্যান্য সমাধান পুনরাবৃত্ত আকারের বৃদ্ধির জন্য আরও ধীরে ধীরে অবনমিত হয়, তবে উইন্ডোর আকার বৃদ্ধির জন্যও অবনমিত হয়)। এমনকি এটি " map(tuple, ...)
আবশ্যকভাবে টিউপলস" কেসটি গুটিয়ে রাখার জন্যও রূপান্তর করা যেতে পারে , যা ফাংশনটিতে টিপলিংটি রাখার চেয়ে সামান্য ধীর হয়ে যায় তবে এটি তুচ্ছ (১-৫% বেশি সময় নেয়) এবং আপনাকে দ্রুত চলার নমনীয়তা রাখতে দেয় যখন আপনি বার বার একই মান ফিরিয়ে সহ্য করতে পারেন।
আপনার যদি রিটার্নগুলি সংরক্ষণের বিরুদ্ধে সুরক্ষার প্রয়োজন consume
হয় তবে ছোট ইনপুট মাপগুলি ব্যতীত ইনলাইন বিজয়গুলি (অ-ইনলাইনড consume
কিছুটা ধীর হলেও একইভাবে স্কেলিং সহ)। deque
& Tupling ভিত্তিক সমাধান জয়ী শুধুমাত্র ক্ষুদ্রতম ইনপুট ছোট সেটআপ খরচ কারণে জন্য, এবং লাভ ছোট; এটি খারাপভাবে হ্রাস পায় কারণ পুনরাবৃত্তিযোগ্য দীর্ঘ হয়।
রেকর্ড, kindall এর সমাধান যে অভিযোজিত সংস্করণের জন্য yield
গুলি tuple
গুলি আমি ব্যবহার ছিল:
def windowkindalltupled(iterable, n=2, tuple=tuple):
it = iter(iterable)
win = deque(islice(it, n), n)
if len(win) < n:
return
append = win.append
yield tuple(win)
for e in it:
append(e)
yield tuple(win)
এর ক্যাশে ছাড়ুন tuple
ফাংশন সংজ্ঞা লাইন এবং ব্যবহারের tuple
প্রতিটি yield
দ্রুততর কিন্তু কম নিরাপদ সংস্করণ পেতে।
sum()
বাmax()
) এটি মনে রাখা উচিত যে স্থির সময়ে প্রতিটি উইন্ডোর জন্য নতুন মান গণনা করার জন্য দক্ষ অ্যালগরিদম রয়েছে (উইন্ডোর আকার নির্বিশেষে)। আমি পাইথন লাইব্রেরিতে এই কয়েকটি অ্যালগরিদম একসাথে সংগ্রহ করেছি: ঘূর্ণায়মান ।