একটি তালিকায় কোনও উপাদানটির সমস্ত উপস্থিতি কীভাবে সন্ধান করবেন?


377

index()কেবলমাত্র একটি তালিকায় কোনও আইটেমের প্রথম উপস্থিতি দেবে। একটি ঝরঝরে কৌশল যা তালিকার সমস্ত সূচক ফেরত দেয়?


1
আমি এই প্রশ্নটি থেকে কিছুটা বিভ্রান্ত: আপনি কি বহুমাত্রিক তালিকার সমস্ত স্তরে পুনরাবৃত্তভাবে কোনও আইটেম অনুসন্ধান করতে চান, বা আপনি কেবল তালিকার শীর্ষ স্তরের উপস্থিতিগুলি অনুসন্ধান করতে চান?
অ্যান্ডারসন সবুজ

22
আমার মতে একটি তালিকা পদ্ধতি থাকা উচিত যা এটি ঠিকভাবে করে।
otocan

উত্তর:


544

আপনি একটি তালিকা বোধগম্যতা ব্যবহার করতে পারেন:

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

3
পুরানো অজগরগুলিতে, একই কার্যকারিতার জন্য ফিল্টার () ব্যবহার করুন।
গ্লেনো

44
অজগরটিতে তালিকা বোধগম্যতা enumerate২.৩ এ দেখানো হয়েছে, ২.৩ এ। হ্যাঁ, যদি আপনার পাইথনটি প্রাচীন হয় তবে ব্যবহার করুন filter()
স্টিভেন রাম্বালস্কি

2
এই কৌশলটি কোনও বহুমাত্রিক অ্যারেতে কোনও আইটেমের সমস্ত উপস্থিতি খুঁজে পাবে না। উদাহরণস্বরূপ, পরিবর্তে print([i for i, x in enumerate([[1,1],[0,1]]) if x == 1])ফিরে আসে । [][[0, 1], [0, 0], [1, 1]]
অ্যান্ডারসন গ্রিন

9
@ অ্যান্ডারসগ্রিন: "বহুমাত্রিক অ্যারে" শব্দটি এমন একটি ডেটা স্ট্রাকচারের পরামর্শ দেয় যা এর প্রতিটি অক্ষের সাথে একই আকারের গ্যারান্টিযুক্ত। প্লেইন পাইথনে এ জাতীয় কোনও ডেটা কাঠামো নেই। তালিকাগুলির তালিকাগুলি রয়েছে তবে সেগুলি "বহুমাত্রিক অ্যারে" থেকে খুব আলাদা। আপনি যদি পরবর্তীটি চান তবে আপনার NumPy ব্যবহার করা উচিত, যা আপনাকে (a == 1).nonzero()NumPy অ্যারের মতো কাজ করতে দেয় a
সোভেন মারনাচ 14

2
@ ম্যাডম্যানলি আপনি যদি কিছু দ্রুত চান তবে নুমপি ব্যবহার করুন। জোশএডেলের
জর্জি

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
আমি লক্ষ্য করেছি [0] শেষে একটি স্ট্রিতে অ্যারে কী হবে তা রূপান্তরিত করে। আপনি কেন এটি করতে বেছে নিয়েছেন তা আমি আগ্রহী।
অ্যামেলিয়া

5
@ এমেলিয়া [0]প্রয়োজন 'কারণটি whereএকটি (array([2, 8], dtype=int64),)
দ্বৈত

1
আরে @ উইনানড আমি রেখেছি [0] তবে এখনও উভয় অংশ পেয়েছি। আমার কোডটি এখানে রয়েছে: আমাকে আমি কী ভুল করেছি
টোমর

2
@ টমর সবার আগে all_id_resp_addressহওয়া উচিত np.arrayনয় list
উইনানড

1
@ টমর আপনি তুলনা করার চেষ্টা করেছেন listএবং strস্পষ্টতই আপনি পাস Falseকরেছেন np.where। যখন আপনি np.arrayস্মেথের সাথে তুলনা করেন। আপনি বুলিয়ান মানগুলির একটি অ্যারে পাবেন। তারপরে সেই অ্যারের 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বৃহত তালিকার সাথে তালিকার বোঝাপড়ার চেয়ে অনেক দ্রুত faster আপনার যদি ইতিমধ্যে অ্যারে থাকে তবে এটি numpyসমাধানের চেয়েও ধীর গতির হয় , অন্যথায় রূপান্তরকরণের ব্যয় গতি অর্জনকে ছাড়িয়ে যায় (100, 1000 এবং 10000 উপাদানগুলির সাথে পূর্ণসংখ্যার তালিকাগুলিতে পরীক্ষা করা হয়)।

দ্রষ্টব্য: ক্রিস_আর্যান্ডসের মন্তব্যের ভিত্তিতে সতর্কতার একটি নোট: ফলাফলগুলি পর্যাপ্ত পরিমাণে ছড়িয়ে ছিটিয়ে থাকলে এই সমাধান তালিকা বোধের চেয়ে দ্রুততর, তবে যদি তালিকার এমন অনেক উপাদান রয়েছে যা অনুসন্ধান করা হচ্ছে (তালিকার 15% ডলারের বেশি) , 1000 পূর্ণসংখ্যার একটি তালিকা সহ একটি পরীক্ষায়), তালিকা বোঝার দ্রুত হয়।


3
আপনি বলছেন এটি একটি তালিকা সংযোগের চেয়ে দ্রুত, আপনি কি আপনার সময় প্রদর্শন করতে পারবেন যা এটি প্রদর্শন করে?
ক্রিস_রান্ডস

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ইদানীং পারফরম্যান্সে খুব অস্থির হয়ে
উঠেছে


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

পাইথন 2 এ ফিল্টার () ব্যবহার করা।

>>> 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

সমস্ত উপস্থিতি এবং এক বা একাধিক (অভিন্ন) আইটেমের তালিকায় অবস্থান নেওয়া

গণনা করা (অলিস্ট) দিয়ে আপনি প্রথম উপাদানটি (এন) সংরক্ষণ করতে পারেন যা তালিকার সূচী হয় যখন এলিমেন্টটি আপনি যা পছন্দ করেন তার সমান হয়।

>>> 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

এই উত্তরটি আমার বিদ্যমান কোডটিতে প্রয়োগ করা আমার পক্ষে সবচেয়ে সহজ ছিল।
রায়ান হ্যারিস 19

2

একটি ব্যবহার করে for-loop:

  • উত্তর enumerateএবং একটি তালিকা বোধগম্য আরও দক্ষ এবং পাইথোনিক, তবে, এই উত্তরটি এমন শিক্ষার্থীদের উদ্দেশ্যে করা হয়েছে যারা এই বিল্ট-ইন ফাংশনগুলির কিছু ব্যবহার করার অনুমতি পাবে না ।
  • একটি খালি তালিকা তৈরি করুন, indices
  • এর সাহায্যে লুপটি তৈরি করুন for i in range(len(x)):যা সূচী অবস্থানগুলির তালিকার মাধ্যমে মূলত পুনরাবৃত্তি করে[0, 1, 2, 3, ..., len(x)-1]
  • লুপে, কোনও যোগ করুন i, যেখানে x[i]কোনও মিল আছে valuetoindices
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]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.