মূল প্রশ্নটি ছিল:
কোনও তালিকায় কোনও মান বিদ্যমান (লক্ষ লক্ষ মান সহ একটি তালিকা) এবং এর সূচকটি কী কী তা জানার দ্রুততম উপায় কী?
সুতরাং দুটি জিনিস খুঁজে পেতে হবে:
- তালিকার একটি আইটেম, এবং
- সূচকটি কী (তালিকায় থাকলে)।
এর দিকে, আমি সমস্ত ক্ষেত্রে সূচকগুলি গণনা করতে @ xslittlegrass কোডটি সংশোধন করেছি এবং একটি অতিরিক্ত পদ্ধতি যুক্ত করেছি।
ফলাফল
পদ্ধতিগুলি হ'ল:
- ইন - মূলত যদি এক্স ইন বি: রিটার্ন b.index (x)
- চেষ্টা করুন - বি.আইনডেক্স (এক্স) এ চেষ্টা করুন / ধরুন (এক্স-কে বি তে পরীক্ষা করতে হবে)
- সেট - মূলত x সেটে x (b): রিটার্ন b.index (x)
- দ্বিখণ্ডিত - এর সূচির সাথে বিটিকে সাজান, সাজানো (খ) এর জন্য বাইনারি অনুসন্ধান করুন। @ Xslittlegrass এর কাছ থেকে নোট মোড যিনি মূল খের পরিবর্তে বাছাই করা খে সূচকটি ফেরান)
- বিপরীত - খ জন্য একটি বিপরীত অনুসন্ধান অভিধান গঠন; তারপরে d [x] x এর সূচক সরবরাহ করে।
ফলাফলগুলি দেখায় যে 5 পদ্ধতিটি সবচেয়ে দ্রুত।
মজার বিষয় হল চেষ্টা এবং সেট পদ্ধতিগুলি সময়ের সাথে সমান।
পরীক্ষার কোড
import random
import bisect
import matplotlib.pyplot as plt
import math
import timeit
import itertools
def wrapper(func, *args, **kwargs):
" Use to produced 0 argument function for call it"
# Reference https://www.pythoncentral.io/time-a-python-function/
def wrapped():
return func(*args, **kwargs)
return wrapped
def method_in(a,b,c):
for i,x in enumerate(a):
if x in b:
c[i] = b.index(x)
else:
c[i] = -1
return c
def method_try(a,b,c):
for i, x in enumerate(a):
try:
c[i] = b.index(x)
except ValueError:
c[i] = -1
def method_set_in(a,b,c):
s = set(b)
for i,x in enumerate(a):
if x in s:
c[i] = b.index(x)
else:
c[i] = -1
return c
def method_bisect(a,b,c):
" Finds indexes using bisection "
# Create a sorted b with its index
bsorted = sorted([(x, i) for i, x in enumerate(b)], key = lambda t: t[0])
for i,x in enumerate(a):
index = bisect.bisect_left(bsorted,(x, ))
c[i] = -1
if index < len(a):
if x == bsorted[index][0]:
c[i] = bsorted[index][1] # index in the b array
return c
def method_reverse_lookup(a, b, c):
reverse_lookup = {x:i for i, x in enumerate(b)}
for i, x in enumerate(a):
c[i] = reverse_lookup.get(x, -1)
return c
def profile():
Nls = [x for x in range(1000,20000,1000)]
number_iterations = 10
methods = [method_in, method_try, method_set_in, method_bisect, method_reverse_lookup]
time_methods = [[] for _ in range(len(methods))]
for N in Nls:
a = [x for x in range(0,N)]
random.shuffle(a)
b = [x for x in range(0,N)]
random.shuffle(b)
c = [0 for x in range(0,N)]
for i, func in enumerate(methods):
wrapped = wrapper(func, a, b, c)
time_methods[i].append(math.log(timeit.timeit(wrapped, number=number_iterations)))
markers = itertools.cycle(('o', '+', '.', '>', '2'))
colors = itertools.cycle(('r', 'b', 'g', 'y', 'c'))
labels = itertools.cycle(('in', 'try', 'set', 'bisect', 'reverse'))
for i in range(len(time_methods)):
plt.plot(Nls,time_methods[i],marker = next(markers),color=next(colors),linestyle='-',label=next(labels))
plt.xlabel('list size', fontsize=18)
plt.ylabel('log(time)', fontsize=18)
plt.legend(loc = 'upper left')
plt.show()
profile()
bisect
মডিউলটি ব্যবহার করুন