[Python] किसी सूची में कोई मान मौजूद है या नहीं, यह जांचने का सबसे तेज़ तरीका


Answers

जैसा कि दूसरों ने कहा है, बड़ी सूचियों के लिए बहुत धीमी हो सकती है। यहां set , set और bisect के प्रदर्शन की कुछ तुलनाएं दी गई हैं। ध्यान दें कि समय (दूसरे में) लॉग स्केल में है।

परीक्षण के लिए कोड:

import random
import bisect
import matplotlib.pyplot as plt
import math
import time

def method_in(a,b,c):
    start_time = time.time()
    for i,x in enumerate(a):
        if x in b:
            c[i] = 1
    return(time.time()-start_time)   

def method_set_in(a,b,c):
    start_time = time.time()
    s = set(b)
    for i,x in enumerate(a):
        if x in s:
            c[i] = 1
    return(time.time()-start_time)

def method_bisect(a,b,c):
    start_time = time.time()
    b.sort()
    for i,x in enumerate(a):
        index = bisect.bisect_left(b,x)
        if index < len(a):
            if x == b[index]:
                c[i] = 1
    return(time.time()-start_time)

def profile():
    time_method_in = []
    time_method_set_in = []
    time_method_bisect = []

    Nls = [x for x in range(1000,20000,1000)]
    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)]

        time_method_in.append(math.log(method_in(a,b,c)))
        time_method_set_in.append(math.log(method_set_in(a,b,c)))
        time_method_bisect.append(math.log(method_bisect(a,b,c)))

    plt.plot(Nls,time_method_in,marker='o',color='r',linestyle='-',label='in')
    plt.plot(Nls,time_method_set_in,marker='o',color='b',linestyle='-',label='set')
    plt.plot(Nls,time_method_bisect,marker='o',color='g',linestyle='-',label='bisect')
    plt.xlabel('list size', fontsize=18)
    plt.ylabel('log(time)', fontsize=18)
    plt.legend(loc = 'upper left')
    plt.show()
Question

मैं यह जानने का सबसे तेज़ तरीका खोज रहा हूं कि किसी सूची में कोई मान मौजूद है (इसमें लाखों मूल्यों वाली एक सूची) और इसकी अनुक्रमणिका क्या है? मुझे पता है कि सूची में सभी मूल्य मेरे उदाहरण की तरह अद्वितीय हैं।

पहली विधि मैं कोशिश करता हूं (3.8sec मेरे असली कोड में):

a = [4,2,3,1,5,6]

if a.count(7) == 1:
    b=a.index(7)
    "Do something with variable b"

दूसरी विधि मैं कोशिश करता हूं (2x तेज: 1.9sec मेरे असली कोड पर):

a = [4,2,3,1,5,6]

try:
    b=a.index(7)
except ValueError:
    "Do nothing"
else:
    "Do something with variable b"

उपयोगकर्ता से प्रस्तावित तरीके (2.74sec मेरे असली कोड पर):

a = [4,2,3,1,5,6]
if 7 in a:
    a.index(7)

मेरे वास्तविक कोड में, पहली विधि 3.81sec लेती है और दूसरी विधि 1.88sec लेती है। यह एक अच्छा सुधार है लेकिन:

मैं पाइथन / स्क्रिप्टिंग के साथ एक नौसिखिया हूं और मैं जानना चाहता हूं कि एक ही चीज करने के लिए सबसे तेज़ तरीका मौजूद है और अधिक प्रक्रिया समय बचाता है?

मेरे आवेदन के लिए अधिक विशिष्ट व्याख्या:

ब्लेंडर के एपीआई में कणों की एक सूची तक पहुंच सकते हैं:

particles = [1,2,3,4...etc.]

वहां से, मैं इसके स्थान तक पहुंच सकता हूं:

particles[x].location = [x,y,z]

और यदि प्रत्येक पड़ोसी के स्थान में खोज करके एक पड़ोसी मौजूद होता है तो मैं प्रत्येक कण के लिए परीक्षण करता हूं:

if [x+1,y,z] in particles.location
    "find the identity of this neighbour particles in x:the index 
    of the particles array"
    particles.index([x+1,y,z])



आप अपने सामान को एक set में डाल सकते हैं। सेट लुकअप बहुत ही कुशल हैं।

प्रयत्न:

s = set(a)
if 7 in s:
  # do stuff

एक टिप्पणी में संपादित करें आप कहते हैं कि आप तत्व की अनुक्रमणिका प्राप्त करना चाहते हैं। दुर्भाग्य से, सेट तत्व की स्थिति की कोई धारणा नहीं है। एक विकल्प है अपनी सूची को पूर्व-क्रमबद्ध करना और फिर हर बार आपको तत्व खोजने की आवश्यकता होने पर बाइनरी खोज का उपयोग करना है।




ऐसा लगता है कि आपके एप्लिकेशन को ब्लूम फ़िल्टर डेटा संरचना के उपयोग से लाभ प्राप्त हो सकता है।

संक्षेप में, एक ब्लूम फ़िल्टर लुक-अप आपको बहुत जल्दी बता सकता है यदि कोई मान निश्चित रूप से सेट में मौजूद नहीं है। अन्यथा, आप उस मूल्य की अनुक्रमणिका प्राप्त करने के लिए धीमे रूप से देख सकते हैं जो संभावित रूप से सूची में हो सकता है। इसलिए यदि आपका एप्लिकेशन "नहीं मिला" परिणाम प्राप्त करता है तो अक्सर "पाया" परिणाम मिलता है, तो आप ब्लूम फ़िल्टर जोड़कर एक गति देख सकते हैं।

विवरण के लिए, विकिपीडिया ब्लूम फ़िल्टर कैसे काम करता है, और "पायथन ब्लूम फ़िल्टर लाइब्रेरी" के लिए एक वेब खोज का एक अच्छा अवलोकन प्रदान करता है, कम से कम कुछ उपयोगी कार्यान्वयन प्रदान करेगा।




present = False
searchItem = 'd'
myList = ['a', 'b', 'c', 'd', 'e']
if searchItem in myList:
   present = True
   print('present = ', present)
else:
   print('present = ', present)



मेरे लिए यह 0.030 (वास्तविक), 0.026s (उपयोगकर्ता) और 0.004s (sys) था।

try:
print("Started")
x = ["a", "b", "c", "d", "e", "f"]

i = 0

while i < len(x):
    i += 1
    if x[i] == "e":
        print("Found")
except IndexError:
    pass





Links