किसी सूची में पहला सूचकांक जो x से अधिक है, उसे खोजने का सबसे पाइथोनिक तरीका क्या होगा?
उदाहरण के लिए, साथ
list = [0.5, 0.3, 0.9, 0.8]
कार्यक्रम
f(list, 0.7)
लौटूंगा
2.
किसी सूची में पहला सूचकांक जो x से अधिक है, उसे खोजने का सबसे पाइथोनिक तरीका क्या होगा?
उदाहरण के लिए, साथ
list = [0.5, 0.3, 0.9, 0.8]
कार्यक्रम
f(list, 0.7)
लौटूंगा
2.
2
क्योंकि 0.9 > 0.7
या क्योंकि 0.8 > 0.7
? दूसरे शब्दों में, क्या आप क्रमिक रूप से या बढ़ते मूल्यों के क्रम में खोज रहे हैं?
जवाबों:
next(x[0] for x in enumerate(L) if x[1] > 0.7)
next()
, लेकिन शायद पठनीयता के लिए:next(i for i,v in enumerate(L) if v > 0.7)
itertools.chain()
इस तरह सूचियों को जोड़ने के बजाय उपयोग करें ।
next((i for i, x in enumerate(L) if x > value), -1)
यदि सूची को क्रमबद्ध किया जाता है, तो bisect.bisect_left(alist, value)
बड़ी सूची के लिए तेजी से होता है next(i for i, x in enumerate(alist) if x >= value)
।
bisect_left
O (n n) है, जबकि listcomp हे (n) यानी, जितना बड़ा n
, उतना ही अधिक लाभ bisect_left()
। मैं के सूचकांक को खोजने के लिए कोशिश की है 500_000
में range(10**6)
उपयोग करते हुए bisect_left()
> 3.75 माइक्रोसेकंड और साथ genexpr का उपयोग कर - next()
- [> 51.0 मिलीसेकेंड 10_000
बार] धीमी रूप में की उम्मीद।
filter(lambda x: x>.7, seq)[0]
bisect_left()
(सबसे तेज) और enumerate()
।
>>> alist= [0.5, 0.3, 0.9, 0.8]
>>> [ n for n,i in enumerate(alist) if i>0.7 ][0]
2
IndexError: list index out of range
:। index = next[ n for n,i in enumerate(alist) if i>0.7 ]
त्रुटि का उपयोग कर देता है NameError: name 'index' is not defined
:। next
थोड़ा तेज है: 60 000 नंबरों के लिए समय का अंतर 12.7 एनएस बनाम 11.9 एनएस है।
for index, elem in enumerate(elements):
if elem > reference:
return index
raise ValueError("Nothing Found")
और एक:
map(lambda x: x>.7, seq).index(True)
1) सामान्य ARGWHERE, सामान्य सूचियाँ
यदि आप सुन्न का उपयोग करने के लिए खुश हैं, तो निम्नलिखित सामान्य सूचियों पर काम करेगा (सॉर्ट या अनसर्टेड):
numpy.argwhere(np.array(searchlist)>x)[0]
या यदि आपको सूची के रूप में उत्तर की आवश्यकता है:
numpy.argwhere(np.array(searchlist)>x).tolist()[0]
या यदि आपको पूर्णांक सूचकांक के रूप में उत्तर की आवश्यकता है:
numpy.argwhere(np.array(searchlist)>x).tolist()[0][0]
2) NUMPY खोजा, क्रमबद्ध सूची (खोज सूचियों के लिए बहुत ही कुशल)
हालाँकि, यदि आपकी खोज सूची को क्रमबद्ध किया जाता है, तो यह फ़ंक्शन np.searchsorted का उपयोग करने के लिए बहुत क्लीनर और अच्छा है :
numpy.searchsorted(searchlist,x)
इस फ़ंक्शन का उपयोग करने के बारे में अच्छी बात यह है कि एकल मान x के लिए खोज करने के साथ-साथ, x भी एक सूची हो सकती है, यानी आप खोजे गए मानों की सूची के लिए सूचकांकों की सूची भी वापस कर सकते हैं [X1, x2, x3 .. xn ], ( और यह इस मामले में एक सूची समझ के सापेक्ष बहुत कुशल है )।
जब मेरी सूची बहुत लंबी थी तो मुझे भी ऐसी ही समस्या थी। समझ या फ़िल्टर आधारित समाधान पूरी सूची के माध्यम से चले जाएंगे। itertools.takewhile पहली बार झूठी होने के बाद लूप को तोड़ देगा:
from itertools import takewhile
def f(l, b): return len([x for x in takewhile(lambda x: x[1] <= b, enumerate(l))])
l = [0.5, 0.3, 0.9, 0.8]
f(l, 0.7)
मुझे पता है कि पहले से ही बहुत सारे उत्तर हैं, लेकिन मुझे कभी-कभी लगता है कि पायथोनिक शब्द का अनुवाद 'वन-लाइनर' में किया गया है।
जब मुझे लगता है कि एक बेहतर परिभाषा इस उत्तर के करीब है :
"स्पष्ट, संक्षिप्त और बनाए रखने वाले कोड का उत्पादन करने के लिए पायथन भाषा की सुविधाओं को उजागर करना।"
हालांकि उपर्युक्त उत्तरों में से कुछ संक्षिप्त हैं, मुझे उन्हें स्पष्ट नहीं लगता है और यह समझने में थोड़ी देर के लिए एक नौसिखिया प्रोग्रामर ले जाएगा, इसलिए कई कौशल स्तरों से बनी टीम के लिए उन्हें अत्यधिक बनाए रखने की आवश्यकता नहीं है।
l = [0.5, 0.3, 0.9, 0.8]
def f(l, x):
for i in l:
if i >x: break
return l.index(i)
f(l,.7)
या
l = [0.5, 0.3, 0.9, 0.8]
def f(l, x):
for i in l:
if i >x: return l.index(i)
f(l,.7)
मुझे लगता है कि ऊपर एक नौसिखिया द्वारा आसानी से समझा जाता है और अभी भी किसी भी अनुभवी अजगर प्रोग्रामर द्वारा स्वीकार किए जाने के लिए पर्याप्त संक्षिप्त है।
मुझे लगता है कि गूंगा कोड लिखना एक सकारात्मक है।
>>> f=lambda seq, m: [ii for ii in xrange(0, len(seq)) if seq[ii] > m][0]
>>> f([.5, .3, .9, .8], 0.7)
2
आप इसका उपयोग भी कर सकते हैं numpy
:
import numpy as np
list(np.array(SearchList) > x).index(True)
इसको आजमाओ:
def Renumerate(l):
return [(len(l) - x, y) for x,y in enumerate(l)]
उदाहरण कोड:
Renumerate(range(10))
उत्पादन:
(10, 0)
(9, 1)
(8, 2)
(7, 3)
(6, 4)
(5, 5)
(4, 6)
(3, 7)
(2, 8)
(1, 9)