প্রস্তাবিত অনেকগুলি সমাধান সহ, আমি অবাক হয়েছি কারও প্রস্তাবিত প্রস্তাব আমি কী প্রকাশ্য হিসাবে বিবেচনা করব (নন-হ্যাশযোগ্য কিন্তু তুলনীয় উপাদানগুলির জন্য) - [ itertools.groupby
] [1]। itertools
দ্রুত, পুনরায় ব্যবহারযোগ্য কার্যকারিতা সরবরাহ করে এবং আপনাকে স্ট্যান্ডার্ড লাইব্রেরি উপাদানগুলিতে কিছু জটিল যুক্তি সরবরাহ করতে দেয়। উদাহরণস্বরূপ বিবেচনা করুন:
import itertools
import operator
def most_common(L):
# get an iterable of (item, iterable) pairs
SL = sorted((x, i) for i, x in enumerate(L))
# print 'SL:', SL
groups = itertools.groupby(SL, key=operator.itemgetter(0))
# auxiliary function to get "quality" for an item
def _auxfun(g):
item, iterable = g
count = 0
min_index = len(L)
for _, where in iterable:
count += 1
min_index = min(min_index, where)
# print 'item %r, count %r, minind %r' % (item, count, min_index)
return count, -min_index
# pick the highest-count/earliest item
return max(groups, key=_auxfun)[0]
এটি অবশ্যই আরও সংক্ষিপ্তভাবে লেখা যেতে পারে, তবে আমি সর্বাধিক স্বচ্ছতার জন্য লক্ষ্য করছি। দুটি print
বিবৃতিটি ক্রিয়াকলাপে যন্ত্রপাতিটি আরও ভালভাবে দেখার জন্য আপত্তিহীন হতে পারে; উদাহরণস্বরূপ, নিরক্ষিত প্রিন্ট সহ :
print most_common(['goose', 'duck', 'duck', 'goose'])
নিঃসরণ করে:
SL: [('duck', 1), ('duck', 2), ('goose', 0), ('goose', 3)]
item 'duck', count 2, minind 1
item 'goose', count 2, minind 0
goose
আপনি দেখতে পাচ্ছেন, SL
জোড়ার একটি তালিকা, প্রতিটি জুড়ি একটি আইটেমের পরে মূল তালিকার আইটেমের সূচক অনুসরণ করে (মূল শর্তটি বাস্তবায়নের জন্য, যদি একই সর্বোচ্চ গণনা সহ "সবচেয়ে সাধারণ" আইটেমগুলি> 1 হয় তবে ফলাফল অবশ্যই আবশ্যক সর্বাধিক সংঘটিত হতে হবে)।
groupby
শুধুমাত্র আইটেম দ্বারা (মাধ্যমে operator.itemgetter
) গ্রুপ। max
গণনার সময় গোষ্ঠী প্রতি একবার বলা হয় সহায়ক ফাংশন, একটি গ্রুপ গ্রহণ করে এবং অভ্যন্তরীণভাবে একটি গোষ্ঠী (item, iterable)
আনপ্যাক করে - এমন দুটি আইটেমের সাথে একটি টুপল যেখানে পুনরাবৃত্তকারীগুলির আইটেমগুলি দ্বি-আইটেম টুপলস, (item, original index)
[[এর আইটেম SL
]] থাকে।
তারপরে সহায়ক ফাংশনটি গ্রুপের পুনরাবৃত্তীয়গুলিতে প্রবেশের গণনা এবং সর্বনিম্ন মূল সূচক উভয় নির্ধারণ করতে একটি লুপ ব্যবহার করে ; এটি মিশ্রিত "মানের কী" হিসাবে তাদের ফিরিয়ে দেয়, নূন্যতম সূচি সাইন-পরিবর্তনের সাথে যাতে max
ক্রিয়াকলাপটি মূল তালিকায় এর আগে ঘটেছিল সেই আইটেমগুলিকে "আরও ভাল" বিবেচনা করবে।
সময় এবং স্থানের বড়-ও ইস্যুগুলি সম্পর্কে কিছুটা কম চিন্তিত থাকলে এই কোডটি আরও সহজ হতে পারে , যেমন ...:
def most_common(L):
groups = itertools.groupby(sorted(L))
def _auxfun((item, iterable)):
return len(list(iterable)), -L.index(item)
return max(groups, key=_auxfun)[0]
একই বেসিক ধারণাটি স্রেফ আরও সহজ এবং সংক্ষিপ্তভাবে প্রকাশ করেছে ... তবে হায়, অতিরিক্ত একটি O (N) সহায়ক স্থান (গ্রুপগুলির তালিকায় পুনরাবৃত্ত হওয়ার জন্য) এবং হে (এন স্কোয়ার) সময় ( L.index
প্রতিটি আইটেমের জন্য) । যদিও অকালীন অপ্টিমাইজেশান প্রোগ্রামিংয়ের সমস্ত অশুভের মূল, যখন ও (এন লগ এন) পাওয়া যায় তখন ইচ্ছাকৃতভাবে একটি ও (এন স্কোয়ার্ড) পদ্ধতির বাছাই করা হয় যখন স্কেলাবিলিটির শস্যের বিপরীতে খুব বেশি যায়! -)
পরিশেষে, যারা স্বচ্ছতা এবং পারফরম্যান্সের জন্য "oneliners" পছন্দ করেন তাদের পক্ষে উপযুক্তভাবে ম্যাংলেড নামের একটি বোনাস 1-লাইনার সংস্করণ :-)।
from itertools import groupby as g
def most_common_oneliner(L):
return max(g(sorted(L)), key=lambda(x, v):(len(list(v)),-L.index(x)))[0]