Python Language
खोज कर
खोज…
टिप्पणियों
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__
विधि लागू करता है।