खोज…


टिप्पणियों

n तत्वों से युक्त पुनरावृत्तियों पर सभी खोज एल्गोरिदम में O(n) जटिलता है। केवल विशिष्ट एल्गोरिदम जैसे कि bisect.bisect_left() O(log(n)) जटिलता के साथ तेज हो सकता है।

स्ट्रिंग्स के लिए सूचकांक प्राप्त करना: str.index (), str.rindex () और str.find (), str.indfind ()

String में एक index विधि भी है, लेकिन अधिक उन्नत विकल्प और अतिरिक्त str.find । इन दोनों के लिए एक पूरक उलट विधि है।

astring = 'Hello on StackOverflow'
astring.index('o')  # 4
astring.rindex('o') # 20

astring.find('o')   # 4
astring.rfind('o')  # 20

के बीच अंतर index / rindex और find / rfind तो क्या होता है-स्ट्रिंग स्ट्रिंग में नहीं पाया जाता है:

astring.index('q') # ValueError: substring not found
astring.find('q')  # -1

ये सभी विधियाँ एक आरंभ और अंत सूचकांक की अनुमति देती हैं:

astring.index('o', 5)    # 6
astring.index('o', 6)    # 6 - start is inclusive
astring.index('o', 5, 7) # 6
astring.index('o', 5, 6) #  - end is not inclusive

ValueError: विकल्प नहीं मिला

astring.rindex('o', 20) # 20 
astring.rindex('o', 19) # 20 - still from left to right

astring.rindex('o', 4, 7) # 6

किसी तत्व की खोज करना

पायथन में निर्मित सभी संग्रह तत्वों का उपयोग करके सदस्यता की जांच करने का तरीका लागू करते in

सूची

alist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
5 in alist   # True
10 in alist  # False

टपल

atuple = ('0', '1', '2', '3', '4')
4 in atuple    # False
'4' in atuple  # True

तार

astring = 'i am a string'
'a' in astring   # True
'am' in astring  # True
'I' in astring   # False

सेट

aset = {(10, 10), (20, 20), (30, 30)}
(10, 10) in aset  # True
10 in aset        # False

dict

dict थोड़ा खास है: सामान्य in केवल चेकों चाबियाँ। यदि आप उन मूल्यों को खोजना चाहते हैं जिन्हें आपको निर्दिष्ट करने की आवश्यकता है। वही यदि आप कुंजी-मूल्य जोड़े की खोज करना चाहते हैं।

adict = {0: 'a', 1: 'b', 2: 'c', 3: 'd'}
1 in adict                 # True   - implicitly searches in keys
'a' in adict               # False
2 in adict.keys()          # True   - explicitly searches in keys
'a' in adict.values()      # True   - explicitly searches in values
(0, 'a') in adict.items()  # True   - explicitly searches key/value pairs

अनुक्रमणिका सूची और टुपल्स प्राप्त करना: list.index (), tuple.index ()

list और tuple एक है index तत्व की स्थिति को प्राप्त करने के लिए -method:

alist = [10, 16, 26, 5, 2, 19, 105, 26]
# search for 16 in the list
alist.index(16) # 1
alist[1]        # 16

alist.index(15)

ValueError: 15 सूची में नहीं है

लेकिन केवल पहले पाए गए तत्व की स्थिति लौटाता है:

atuple = (10, 16, 26, 5, 2, 19, 105, 26)
atuple.index(26)   # 2
atuple[2]          # 26
atuple[7]          # 26 - is also 26!

तानाशाही में एक मूल्य के लिए कुंजी खोज रहा है

किसी भी मान या कुंजी को खोजने के लिए dict पास कोई अंतर्निहित तरीका नहीं है क्योंकि शब्दकोश अनियंत्रित हैं। आप एक फ़ंक्शन बना सकते हैं जिसे एक निर्दिष्ट मान के लिए कुंजी (या कुंजी) मिलती है:

def getKeysForValue(dictionary, value):
    foundkeys = []
    for keys in dictionary:
        if dictionary[key] == value:
            foundkeys.append(key)
    return foundkeys

इसे एक समकक्ष सूची समझ के रूप में भी लिखा जा सकता है:

def getKeysForValueComp(dictionary, value): 
    return [key for key in dictionary if dictionary[key] == value]

यदि आप केवल एक कुंजी के बारे में परवाह करते हैं:

def getOneKeyForValue(dictionary, value):
    return next(key for key in dictionary if dictionary[key] == value)

पहले दो फ़ंक्शंस में उन सभी keys की list होगी जो निर्दिष्ट मान रखती हैं:

adict = {'a': 10, 'b': 20, 'c': 10}
getKeysForValue(adict, 10)     # ['c', 'a'] - order is random could as well be ['a', 'c']
getKeysForValueComp(adict, 10) # ['c', 'a'] - dito
getKeysForValueComp(adict, 20) # ['b']
getKeysForValueComp(adict, 25) # []

दूसरा केवल एक कुंजी लौटाएगा:

getOneKeyForValue(adict, 10)   # 'c'  - depending on the circumstances this could also be 'a'
getOneKeyForValue(adict, 20)   # 'b'

और एक बढ़ा StopIteration - Exception अगर मूल्य में नहीं है dict :

getOneKeyForValue(adict, 25)

StopIteration

अनुक्रमित अनुक्रमों के लिए सूचकांक प्राप्त करना: bisect.bisect_left ()

क्रमबद्ध अनुक्रम तेजी से खोज एल्गोरिदम के उपयोग की अनुमति देते हैं: bisect.bisect_left() 1 :

import bisect

def index_sorted(sorted_seq, value):
    """Locate the leftmost value exactly equal to x or raise a ValueError"""
    i = bisect.bisect_left(sorted_seq, value)
    if i != len(sorted_seq) and sorted_seq[i] == value:
        return i
    raise ValueError

alist = [i for i in range(1, 100000, 3)] # Sorted list from 1 to 100000 with step 3
index_sorted(alist, 97285) # 32428
index_sorted(alist, 4)     # 1
index_sorted(alist, 97286)

ValueError

बहुत बड़े क्रमबद्ध अनुक्रमों के लिए गति लाभ काफी अधिक हो सकता है। पहले खोज के मामले में लगभग 500 गुना तेजी से:

%timeit index_sorted(alist, 97285)
# 100000 loops, best of 3: 3 µs per loop
%timeit alist.index(97285)
# 1000 loops, best of 3: 1.58 ms per loop

जबकि यह थोड़ा धीमा है यदि तत्व पहले में से एक है:

%timeit index_sorted(alist, 4)
# 100000 loops, best of 3: 2.98 µs per loop
%timeit alist.index(4)
# 1000000 loops, best of 3: 580 ns per loop

नेस्टेड दृश्यों की खोज

एक तरह नीडिंत दृश्यों में सर्च कर रहे हैं list के tuple में मूल्यों के लिए कुंजी खोज की तरह एक दृष्टिकोण की आवश्यकता है dict लेकिन जरूरत है अनुकूलित कार्य करता है।

यदि अनुक्रम में मान पाया गया तो सबसे बाहरी अनुक्रम का सूचकांक:

def outer_index(nested_sequence, value):
    return next(index for index, inner in enumerate(nested_sequence) 
                      for item in inner 
                      if item == value)

alist_of_tuples = [(4, 5, 6), (3, 1, 'a'), (7, 0, 4.3)]
outer_index(alist_of_tuples, 'a')  # 1
outer_index(alist_of_tuples, 4.3)  # 2

या बाहरी और आंतरिक अनुक्रम का सूचकांक:

def outer_inner_index(nested_sequence, value):
    return next((oindex, iindex) for oindex, inner in enumerate(nested_sequence) 
                                 for iindex, item in enumerate(inner) 
                                 if item == value)

outer_inner_index(alist_of_tuples, 'a') # (1, 2)
alist_of_tuples[1][2]  # 'a'

outer_inner_index(alist_of_tuples, 7)   # (2, 0)
alist_of_tuples[2][0]  # 7

सामान्य तौर पर ( हमेशा नहीं ) खोज मूल्य के पहले घटना को खोजने के लिए शर्तों के साथ next और एक जनरेटर अभिव्यक्ति का उपयोग करना सबसे कुशल दृष्टिकोण है।

कस्टम कक्षाओं में खोज: __contains__ और __iter__

के उपयोग की अनुमति के लिए in कस्टम कक्षाओं के लिए वर्ग या तो जादू विधि प्रदान करनी चाहिए __contains__ या, कि, एक नाकाम रहने __iter__ -method।

मान लीजिए कि आपके पास एक वर्ग है जिसमें list की list :

class ListList:
    def __init__(self, value):
        self.value = value
        # Create a set of all values for fast access
        self.setofvalues = set(item for sublist in self.value for item in sublist)
        
    def __iter__(self):
        print('Using __iter__.')
        # A generator over all sublist elements
        return (item for sublist in self.value for item in sublist)
        
    def __contains__(self, value):
        print('Using __contains__.')
        # Just lookup if the value is in the set
        return value in self.setofvalues

        # Even without the set you could use the iter method for the contains-check:
        # return any(item == value for item in iter(self))

सदस्यता परीक्षण का उपयोग करना संभव in :

a = ListList([[1,1,1],[0,1,1],[1,5,1]])
10 in a    # False
# Prints: Using __contains__.
5 in a     # True
# Prints: Using __contains__.

__contains__ विधि को हटाने के बाद भी:

del ListList.__contains__
5 in a     # True
# Prints: Using __iter__.

नोट: वर्ग in ( for i in a में के for i in a रूप में) __iter__ हमेशा __iter__ उपयोग __iter__ भले ही वर्ग एक __contains__ विधि लागू करता है।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow