পাইথনে বস্তুর একটি তালিকা অনুসন্ধান করা হচ্ছে


94

আসুন ধরে নেওয়া যাক আমি কেবলমাত্র সিটি স্টাইলের কাঠামোর মতো কাজ করার জন্য একটি সাধারণ ক্লাস তৈরি করছি, কেবলমাত্র ডেটা উপাদান রাখার জন্য। আমি নির্দিষ্ট মানের সমতুল্য একটি গুণাবলীযুক্ত অবজেক্টগুলির জন্য কীভাবে অবজেক্টগুলির একটি তালিকা অনুসন্ধান করব তা নির্ধারণ করার চেষ্টা করছি। নীচে আমি কী করার চেষ্টা করছি তা বোঝানোর জন্য একটি তুচ্ছ উদাহরণ দেওয়া হল।

এই ক্ষেত্রে:

class Data:
    pass

myList = []

for i in range(20):
    data = Data()
    data.n = i
    data.n_squared = i * i
    myList.append(data)

আমি কীভাবে MyList তালিকায় অনুসন্ধান করতে যাব যাতে এটিতে এন == 5 দিয়ে কোনও উপাদান রয়েছে কিনা তা নির্ধারণ করতে?

আমি পাইগন ডক্সকে গুগলিং এবং অনুসন্ধান করে চলেছি এবং আমি মনে করি যে আমি সম্ভবত তালিকা বোধের সাহায্যে এটি করতে সক্ষম হতে পারি তবে আমি নিশ্চিত নই। আমি যুক্ত করতে পারি যে উপায় দ্বারা আমি পাইথন ২.৪.৩ ব্যবহার করতে পারি, সুতরাং কোনও নতুন জি-হুইস ২.6 বা ৩.x বৈশিষ্ট্য আমার কাছে উপলভ্য নয়।


সম্ভবত আপনার উদাহরণের একটি অনিচ্ছাকৃত গণ্ডগোল: মাইলিস্ট = [ডেটা ()। এন == 0, ডেটা () মাইলিস্টে সূচক। সুতরাং আপনাকে কেবল কোনও সূচক মান দ্বারা মাইলিস্ট উল্লেখ করে কোনও ডেটা () উদাহরণ টানতে দেয়। অবশ্যই আপনি পরে myList [0] .n = 5.2 বা অন্য কিছু পরিবর্তন করতে পারেন। এবং উদাহরণটি সম্ভবত অতি-সরল করা হয়েছিল।
দেবপ্লেয়ার

উত্তর:


139

আপনি একটি তালিকা বোধগম্যতার সাথে সমস্ত মিলে যাওয়া উপাদানের একটি তালিকা পেতে পারেন :

[x for x in myList if x.n == 30]  # list of all elements with .n==30

যদি আপনি কেবল নির্ধারণ করতে চান যে তালিকায় কোনও উপাদান মেলে এবং দক্ষতার সাথে এটি (তুলনামূলকভাবে) করা থাকে তবে আপনি এটি করতে পারেন

def contains(list, filter):
    for x in list:
        if filter(x):
            return True
    return False

if contains(myList, lambda x: x.n == 3)  # True if any element has .n==3
    # do stuff

25
বা, মাইলিস্টে এক্স এর জন্য যে কোনও (কাস্টম_ফিল্টার (এক্স) যদি xn == 30) যা বিল্টিন হিসাবে কেবল আপনার "অন্তর্ভুক্ত" ফাংশন।
nosklo

নসক্লোতে সিনট্যাক্স ত্রুটি - জেনারেটরের চারপাশে একটি অতিরিক্ত সেট প্রয়োজন।
gahooa

তাই না। চেষ্টা করে দেখুন।
রবার্ট রসনি

4
এটা gahooa এর (সঙ্গে এই উত্তর একসঙ্গে মার্জ করতে ভাল হবে stackoverflow.com/a/598602/2349267 )।
রোমান হোয়াং

77

সহজ, মার্জিত এবং শক্তিশালী:

একটি বিল্টিন সহ কনজাকশনে একটি জেনারেটর এক্সপ্রেশন… (অজগর 2.5+)

any(x for x in mylist if x.n == 10)

পাইথন any()বিল্টিন ব্যবহার করে , যা নিম্নলিখিত হিসাবে সংজ্ঞায়িত করা হয়েছে:

যেকোন (পুনরাবৃত্ত) -> সত্য যদি প্রত্যাবর্তনযোগ্য কোনও উপাদান সত্য হয় ফিরে আসুন। সমতুল্য:

def any(iterable):
    for element in iterable:
        if element:
            return True
    return False

ভাল লাগল এফওয়াইআই আপনি কিছু প্যারেন (এছাড়াও == নয় =) সংরক্ষণ করতে কোনও (মাইলিস্টে এক্স এর জন্য xn == 10) করতে পারেন।
জ্যাকব গ্যাব্রিয়েলসন

আমি ব্যবহার পছন্দ করি any(x for x in mylist if x['n'] == 10)তবে ভাল ধারণা
অ্যালেক্স মন্টোয়া

48

কেবলমাত্র সম্পূর্ণতার জন্য, আসুন যে সহজ কাজটি সম্ভবত কাজ করতে পারে তা ভুলে যাবেন না:

for i in list:
  if i.n == 5:
     # do something with it
     print "YAY! Found one!"

39
[x for x in myList if x.n == 30]               # list of all matches
[x.n_squared for x in myList if x.n == 30]     # property of matches
any(x.n == 30 for x in myList)                 # if there is any matches
[i for i,x in enumerate(myList) if x.n == 30]  # indices of all matches

def first(iterable, default=None):
  for item in iterable:
    return item
  return default

first(x for x in myList if x.n == 30)          # the first match, if any

4
"প্রথম" পদ্ধতির কারণে এটি একটি ভাল উত্তর, এটি সম্ভবত সবচেয়ে সাধারণ ব্যবহারের ক্ষেত্রে।
galarant

দুর্দান্ত, ধন্যবাদ! ম্যাচের সূচকগুলি আমি যা খুঁজছিলাম। অন্য ক্ষেত্রটি অ্যাক্সেস করতে তালিকাকে সরাসরি সূচক করতে এটি ব্যবহার করার জন্য কি একটি শর্টকাট রয়েছে? এখন আমি তালিকা এন্ট্রিগুলির একটি তালিকা পেয়েছি (কেবলমাত্র একটি প্রবেশ রয়েছে, সুতরাং এটি একটি আইটেম সহ একটি তালিকা)। সূচীটি পেতে, তালিকাটি সূচী করতে ব্যবহার করার আগে আমাকে ফলাফল [0] করাতে হবে। প্রশ্ন উদাহরণস্বরূপ থেকে আমি একটি নির্দিষ্ট এন থেকে n_squared অ্যাক্সেস করতে চাই: myList [myList.n সূচী == 5] .n_squared
Frieke

32
filter(lambda x: x.n == 5, myList)

25
যে কারও জন্য পাইথন শিখতে চান, ল্যাম্বডা বোঝা বুনিয়াদি।
ভের্টেক

4
ভাল, হ্যাঁ এবং না - অপারেটর.আত্রগ্রেট্টারের মতো কী ফাংশন নির্মাতাদের তালিকা বোধগম্যতা এবং বাছাই সহ, আমি খুব কমই lambdaএস ব্যবহার করি ।
বেন হোয়েট

9

আপনি inকোনও সংগ্রহের কোনও আইটেম সন্ধান করতে এবং আপনার আগ্রহী ক্ষেত্রটি বের করার জন্য একটি তালিকা বোঝার জন্য ব্যবহার করতে পারেন This এটি (তালিকাগুলি, সেট, টিপলস এবং যে কোনও কিছুর সংজ্ঞা দেয় __contains__বা এর জন্য কাজ করে __getitem__)।

if 5 in [data.n for data in myList]:
    print "Found it"

আরো দেখুন:


4

আপনার ক্লাসে আপনার একটি __eq__এবং একটি __hash__পদ্ধতি যুক্ত করা উচিত Data, এটি __dict__গুণাবলী সমান (একই বৈশিষ্ট্য) এবং তার মানগুলিও সমান কিনা তা পরীক্ষা করতে পারে ।

আপনি যদি তা করেন তবে আপনি ব্যবহার করতে পারেন

test = Data()
test.n = 5

found = test in myList

inশব্দ চেক যদি testহয় myList

আপনি যদি কেবলমাত্র এএ nসম্পত্তি করতে চান তবে Data:

class Data(object):
    __slots__ = ['n']
    def __init__(self, n):
        self.n = n
    def __eq__(self, other):
        if not isinstance(other, Data):
            return False
        if self.n != other.n:
            return False
        return True
    def __hash__(self):
        return self.n

    myList = [ Data(1), Data(2), Data(3) ]
    Data(2) in myList  #==> True
    Data(5) in myList  #==> False

3

একটি অভিধান ব্যবহার বিবেচনা করুন:

myDict = {}

for i in range(20):
    myDict[i] = i * i

print(5 in myDict)

অথবা: ডি = ডিক ((আমি, আমি * আমি) আমার সীমার জন্য (20%))
হিউডব্রাউন

এটি আমার প্রশ্নটির উদাহরণ দেওয়ার জন্য তুচ্ছ সমস্যাটি সমাধান করে, তবে আমার মূল প্রশ্নটি সত্যিই সমাধান করেনি। আমি যে উত্তরটি খুঁজছিলাম (5+ বছর আগে) সেটি ছিল তালিকা বোধগম্যতা। :)
m0j0

1

আপনি এটি করতে পারার অন্য উপায়টি হ'ল পরবর্তী () ফাংশনটি ব্যবহার করা।

matched_obj = next(x for x in list if x.n == 10)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.