किसी सूची में एक तत्व के सभी घटनाओं को कैसे ढूंढें?


377

index()किसी सूची में आइटम की पहली घटना देगा। क्या कोई साफ-सुथरी चाल है जो किसी सूची में सभी सूचकांकों को लौटाती है?


1
मैं इस सवाल से थोड़ा उलझन में हूँ: क्या आप एक बहुआयामी सूची के सभी स्तरों में पुनरावर्ती रूप से किसी वस्तु की खोज करना चाहते हैं, या क्या आप केवल सूची के शीर्ष स्तर में होने वाली घटनाओं को खोजना चाहते हैं?
एंडरसन ग्रीन

22
मेरी राय में एक सूची विधि होनी चाहिए जो ठीक यही करती है।
ओटोकेन

जवाबों:


544

आप एक सूची समझ का उपयोग कर सकते हैं:

indices = [i for i, x in enumerate(my_list) if x == "whatever"]

3
पुराने अजगर पर, अनिवार्य रूप से समान कार्यक्षमता के लिए फ़िल्टर () का उपयोग करें।
ग्लेनो

44
2.0 में पायथन enumerateमें 2.3 पर सूची की समझ दिखाई गई । तो हाँ, अगर आपका पायथन प्राचीन है, तो उपयोग करें filter()
स्टीवन रंबलस्की

2
यह तकनीक किसी आइटम की सभी घटनाओं को बहुआयामी सरणी में नहीं पाएगी। उदाहरण के लिए, इसके बजाय print([i for i, x in enumerate([[1,1],[0,1]]) if x == 1])रिटर्न । [][[0, 1], [0, 0], [1, 1]]
एंडरसन ग्रीन

9
@AndersonGreen: शब्द "बहुआयामी सरणी" एक ऐसी डेटा संरचना का सुझाव देता है जिसकी प्रत्येक कुल्हाड़ियों के साथ एक समान आकार की गारंटी है। प्लेन पायथन में ऐसी कोई डेटा संरचना नहीं है। सूचियों की सूची है, लेकिन वे "बहुआयामी सरणियों" से बहुत अलग हैं। यदि आप उत्तरार्द्ध चाहते हैं, तो आपको NumPy का उपयोग करने पर विचार करना चाहिए, जो आपको (a == 1).nonzero()NumPy सरणी के लिए चीजों को करने की अनुमति देता है a
स्वेन मार्नाच

2
@MadmanLee अगर आप कुछ तेज चाहते हैं, तो NumPy का उपयोग करें। का उत्तर देखें JoshAdel
जॉर्जी

117

जबकि सीधे सूचियों के लिए समाधान नहीं, numpyवास्तव में इस तरह की चीज के लिए चमकता है:

import numpy as np
values = np.array([1,2,3,1,2,4,5,6,3,2,1])
searchval = 3
ii = np.where(values == searchval)[0]

रिटर्न:

ii ==>array([2, 8])

यह बड़ी संख्या में तत्वों बनाम कुछ अन्य समाधानों के साथ सूचियों (सरणियों) के लिए काफी तेज हो सकता है।


2
मैंने देखा कि अंत में [०] धर्मान्तरित क्या एक स्ट्रिंग के लिए एक सरणी होगी। मैं उत्सुक हूं कि आपने ऐसा करने का विकल्प क्यों चुना।
अमेलिया

5
@amelia [0]की जरूरत है क्योंकि ' whereरिटर्न टपल(array([2, 8], dtype=int64),)
विनंड

1
हे @Winand मैं [0] में डाल दिया, लेकिन अभी भी दोनों भागों मिलता है। यहाँ मेरा कोड है: (nrg.local_logs.all_id_resp_address एक सूची है) "ste =" 199.38.164.165 "value = np.where (nrg.local_log_all_id_resp_ress_=_ddress == ste) [0]" मैं आपको बताऊं तो मुझे खुशी होगी। मैंने जो किया वह गलत था
तोमर

2
@ सबसे पहले नहीं all_id_resp_addressहोना चाहिए । np.arraylist
Winand

1
@ टॉमर की आपने तुलना करने की कोशिश की listऔर strजाहिर है, आप पास हो Falseगए np.where। जब आप np.arraysmth से तुलना करते हैं। आपको बूलियन मानों की एक सरणी मिलती है। फिर उस सरणी np.whereके सभी Trueमानों की स्थिति का पता लगाता है ।
विन्डैंड

29

एक समाधान का उपयोग कर list.index:

def indices(lst, element):
    result = []
    offset = -1
    while True:
        try:
            offset = lst.index(element, offset+1)
        except ValueError:
            return result
        result.append(offset)

enumerateबड़ी सूचियों के लिए यह सूची की तुलना में बहुत तेज है । यदि आपके पास पहले से ही सरणी है, तो यह numpyसमाधान की तुलना में बहुत धीमा है , अन्यथा गति लाभ को परिवर्तित करने की लागत (100, 1000 और 10000 तत्वों के साथ पूर्णांक सूचियों पर परीक्षण)।

नोट: क्रिस का एक टिप्पणी के आधार पर सावधानी की टिप्पणी: यह समाधान सूची की समझ से अधिक तेज़ है यदि परिणाम पर्याप्त रूप से विरल हैं, लेकिन यदि सूची में तत्व के कई उदाहरण हैं जो खोजा जा रहा है (सूची का ~ 15% से अधिक) , 1000 पूर्णांकों की सूची के साथ एक परीक्षण पर), सूची की समझ तेज है।


3
आप कहते हैं कि यह एक सूची COMP की तुलना में तेज़ है, क्या आप अपनी टाइमिंग दिखा सकते हैं जो इसे प्रदर्शित करता है?
क्रिस_रैंड्स 13

4
यह एक लंबे समय से पहले था, मैं शायद timeit.timeitयादृच्छिक रूप से उत्पन्न सूचियों के साथ उपयोग करता था। हालांकि यह एक महत्वपूर्ण बिंदु है, और मुझे लगता है कि आप क्यों पूछ सकते हैं। उस समय यह मेरे साथ नहीं हुआ था, लेकिन यदि परिणाम पर्याप्त रूप से विरल हैं, तो गति लाभ केवल सच है। मैंने बस खोज करने के लिए तत्व से भरी सूची के साथ परीक्षण किया है, और यह सूची समझ से बहुत धीमी है।
पाउलो अल्मेडा

18

कैसा रहेगा:

In [1]: l=[1,2,3,4,3,2,5,6,7]

In [2]: [i for i,val in enumerate(l) if val==3]
Out[2]: [2, 4]

10
occurrences = lambda s, lst: (i for i,e in enumerate(lst) if e == s)
list(occurrences(1, [1,2,3,1])) # = [0, 3]

8

more_itertools.locate एक शर्त को पूरा करने वाले सभी आइटमों के लिए सूचकांक ढूंढता है।

from more_itertools import locate


list(locate([0, 1, 1, 0, 1, 0, 0]))
# [1, 2, 4]

list(locate(['a', 'b', 'c', 'b'], lambda x: x == 'b'))
# [1, 3]

more_itertoolsएक तृतीय-पक्ष पुस्तकालय है > pip install more_itertools


1
अच्छा हो सकता है अगर इस लिबास को कोंडा-फोर्ज में जोड़ा गया (हालांकि conda installहाल ही में प्रदर्शन में बहुत अस्थिर हो गया है)
Matanster


4

या उपयोग range(अजगर 3):

l=[i for i in range(len(lst)) if lst[i]=='something...']

के लिए (अजगर 2):

l=[i for i in xrange(len(lst)) if lst[i]=='something...']

और फिर (दोनों मामले):

print(l)

जैसी उम्मीद है।


4

Python2 में फ़िल्टर () का उपयोग करना।

>>> q = ['Yeehaw', 'Yeehaw', 'Googol', 'B9', 'Googol', 'NSM', 'B9', 'NSM', 'Dont Ask', 'Googol']
>>> filter(lambda i: q[i]=="Googol", range(len(q)))
[2, 4, 9]

2

आप एक डिफ़ॉल्ट बना सकते हैं

from collections import defaultdict
d1 = defaultdict(int)      # defaults to 0 values for keys
unq = set(lst1)              # lst1 = [1, 2, 2, 3, 4, 1, 2, 7]
for each in unq:
      d1[each] = lst1.count(each)
else:
      print(d1)

2

एक सूची में सभी घटनाओं और एक या अधिक (समान) वस्तुओं की स्थिति प्राप्त करना

गणनाकर्ता (एलिस्ट) के साथ आप पहले तत्व (n) को स्टोर कर सकते हैं जो सूची का सूचकांक है जब तत्व x आपके लिए जो दिखता है उसके बराबर है।

>>> alist = ['foo', 'spam', 'egg', 'foo']
>>> foo_indexes = [n for n,x in enumerate(alist) if x=='foo']
>>> foo_indexes
[0, 3]
>>>

चलिए हमारे फंक्शन को ढूंढते हैं

यह फ़ंक्शन आइटम और सूची को तर्क के रूप में लेता है और सूची में आइटम की स्थिति लौटाता है, जैसे हमने पहले देखा था।

def indexlist(item2find, list_or_string):
  "Returns all indexes of an item in a list or a string"
  return [n for n,item in enumerate(list_or_string) if item==item2find]

print(indexlist("1", "010101010"))

उत्पादन


[1, 3, 5, 7]

सरल

for n, i in enumerate([1, 2, 3, 4, 1]):
    if i == 1:
        print(n)

आउटपुट:

0
4

यह जवाब मेरे लिए मेरे मौजूदा कोड में लागू करना सबसे आसान था।
रयान हैरिस

2

का उपयोग करना for-loop:

  • सूची बोध के साथ उत्तर enumerateऔर अधिक कुशल और पाइथोनिक हैं, हालांकि, यह उत्तर उन छात्रों के लिए है, जिन्हें उन कुछ अंतर्निहित कार्यों का उपयोग करने की अनुमति नहीं दी जा सकती है ।
  • एक खाली सूची बनाएं, indices
  • लूप के साथ बनाएं for i in range(len(x)):, जो अनिवार्य रूप से सूचकांक स्थानों की सूची के माध्यम से पुनरावृत्त करता है[0, 1, 2, 3, ..., len(x)-1]
  • लूप में, कोई भी जोड़ें i, जहां x[i]से मिलान करना है value, कोindices
def get_indices(x: list, value: int) -> list:
    indices = list()
    for i in range(len(x)):
        if x[i] == value:
            indices.append(i)
    return indices

n = [1, 2, 3, -50, -60, 0, 6, 9, -60, -60]
print(get_indices(n, -60))

>>> [4, 8, 9]
  • कार्य, प्रकार के संकेत केget_indices साथ कार्यान्वित किए जाते हैं । इस मामले में, सूची, एस का एक समूह है , इसलिए हम खोज करते हैं , इसे ए के रूप में भी परिभाषित किया गया है ।nintvalueint

एक का उपयोग कर while-loopऔर .index:

def get_indices(x: list, value: int) -> list:
    indices = list()
    i = 0
    while True:
        try:
            # find an occurrence of value and update i to that index
            i = x.index(value, i)
            # add i to the list
            indices.append(i)
            # advance i by 1
            i += 1
        except ValueError as e:
            break
    return indices

print(get_indices(n, -60))
>>> [4, 8, 9]

आपका आत्म-परिभाषित get_indeicesसामान्य सूची की तुलना में थोड़ा तेज (~ 15%) है। मैं इसका पता लगाने की कोशिश कर रहा हूं।
ट्रैविस

1

यदि आप पायथन 2 का उपयोग कर रहे हैं, तो आप इसके साथ समान कार्यक्षमता प्राप्त कर सकते हैं:

f = lambda my_list, value:filter(lambda x: my_list[x] == value, range(len(my_list)))

my_listवह सूची कहां है जिसे आप अनुक्रमणिका प्राप्त करना चाहते हैं, और valueखोजा गया मान है। उपयोग:

f(some_list, some_element)

1

यदि आपको कुछ सूचकांकों के बीच सभी तत्वों की स्थिति की खोज करने की आवश्यकता है , तो आप उन्हें बता सकते हैं:

[i for i,x in enumerate([1,2,3,2]) if x==2 & 2<= i <=3] # -> [3]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.