তালিকায় এমন কোনও বস্তু সন্ধান করুন যা কিছু মানের সমান গুণাবলীযুক্ত (যে কোনও শর্ত পূরণ করে)


221

আমি বস্তুর তালিকা পেয়েছি। আমি এই তালিকার একটি (প্রথম বা যাই হোক না কেন) অবজেক্ট সন্ধান করতে চাই যার সমান গুণ (বা পদ্ধতির ফলাফল - যাই হোক না কেন) রয়েছে value

এটি সন্ধান করার সর্বোত্তম উপায় কী?

এখানে পরীক্ষার কেস:

  class Test:
      def __init__(self, value):
          self.value = value

  import random

  value = 5

  test_list = [Test(random.randint(0,100)) for x in range(1000)]

  # that I would do in Pascal, I don't believe isn't anywhere near 'Pythonic'
  for x in test_list:
      if x.value == value:
          print "i found it!"
          break

আমি মনে করি জেনারেটর ব্যবহার করে এবং reduce()কোনও তাত্পর্য তৈরি করবে না কারণ এটি তালিকার মাধ্যমে পুনরাবৃত্তি হবে।

PS: সমীকরণের valueএকটি উদাহরণ মাত্র। অবশ্যই আমরা এমন উপাদান পেতে চাই যা কোনও শর্ত পূরণ করে।


2
এই প্রশ্নের এখানে একটি ভাল আলোচনা রয়েছে: টমায়কো
অ্যান্ড্রু হরে

মূল পোস্টটি হাস্যকরভাবে তারিখের বাইরে চলে গেছে, তবে ২ য় প্রতিক্রিয়াটি আমার এক-লাইন সংস্করণটির সাথে ঠিক মিলে। যদিও আমি নিশ্চিত নই যে এটি বেসিক লুপ সংস্করণের চেয়ে ভাল।
agf

উত্তর:


433
next((x for x in test_list if x.value == value), None)

এটি তালিকা থেকে প্রথম আইটেমটি পেয়েছে যা শর্তের সাথে মেলে এবং Noneকোনও আইটেম মেলে না তবে ফিরে আসে । এটি আমার পছন্দের একক-প্রকাশের ফর্ম।

যাহোক,

for x in test_list:
    if x.value == value:
        print "i found it!"
        break

নিষ্পাপ লুপ-ব্রেক সংস্করণটি পুরোপুরি পাইথোনিক - এটি সংক্ষিপ্ত, পরিষ্কার এবং দক্ষ। এটি ওয়ান-লাইনারের আচরণের সাথে মেলে তোলে:

for x in test_list:
    if x.value == value:
        print "i found it!"
        break
else:
    x = None

এই দায়িত্ব অর্পণ করবে Noneকরার xযদি আপনি না breakগোষ্ঠীর বাইরে।


72
"নিরীহ লুপ-ব্রেক সংস্করণ পুরোপুরি পাইথোনিক" এর আশ্বাসের জন্য +1
লন্ড্রোম্যাট

দুর্দান্ত সমাধান, তবে আমি কীভাবে আপনার লাইনটি সংশোধন করব যাতে আমি x.value বলতে আসলে x.fieldMemberName বোঝাতে পারি যেখানে সেই নামটির মূল্য রাখা আছে? ফিল্ড = "নাম" পরবর্তী ((x_field == মান যদি x_ টেস্টের তালিকার জন্য x, কোনও কিছুই নয়) যাতে এই ক্ষেত্রে, আমি আসলে x.name এর বিরুদ্ধে পরীক্ষা করছি, এক্সফিল্ড নয়
স্টুয়ার্ট ডেল

3
@ স্টেয়ার্টডেল আপনি যা জিজ্ঞাসা করছেন এটি সম্পূর্ণ পরিষ্কার নয়, তবে আমি মনে করি আপনি বোঝাতে চেয়েছিলেন ... if getattr(x, x.fieldMemberName) == value। এটি xসঞ্চিত নামের সাথে বৈশিষ্ট্যটি আনবে fieldMemberNameএবং এর সাথে তুলনা করবে value
এগ্রিফ

1
@ থাটেকগুয়ে - এই elseধারাটি বোঝানো হয়েছে forলুপে থাকা, নয় if। (প্রত্যাখাত সম্পাদনা)।
agf 2'18

1
@agf বাহ আমার আক্ষরিক অর্থেই কোন ধারণা ছিল না যে .. book.pythontips.com/en/latest/for_-_else.html দুর্দান্ত!
ThatTechGuy

25

যেহেতু এটি কেবল সম্পূর্ণ করার জন্য উল্লেখ করা হয়নি। ফিল্টার করার জন্য ভাল ওল ফিল্টার আপনার ফিল্টারকারী উপাদানগুলি।

কার্যকরী প্রোগ্রামিং ftw।

####### Set Up #######
class X:

    def __init__(self, val):
        self.val = val

elem = 5

my_unfiltered_list = [X(1), X(2), X(3), X(4), X(5), X(5), X(6)]

####### Set Up #######

### Filter one liner ### filter(lambda x: condition(x), some_list)
my_filter_iter = filter(lambda x: x.val == elem, my_unfiltered_list)
### Returns a flippin' iterator at least in Python 3.5 and that's what I'm on

print(next(my_filter_iter).val)
print(next(my_filter_iter).val)
print(next(my_filter_iter).val)

### [1, 2, 3, 4, 5, 5, 6] Will Return: ###
# 5
# 5
# Traceback (most recent call last):
#   File "C:\Users\mousavin\workspace\Scripts\test.py", line 22, in <module>
#     print(next(my_filter_iter).value)
# StopIteration


# You can do that None stuff or whatever at this point, if you don't like exceptions.

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

সুতরাং আপনি সেখানে যান। আপনার কার্যকরী প্রোগ্রামিং জেনে নিন।

ফিল্টার শর্ত তালিকা

এটি এর চেয়ে সহজ আর পাবেন না:

next(filter(lambda x: x.val == value,  my_unfiltered_list)) # Optionally: next(..., None) or some other default value to prevent Exceptions

আমি এর স্টাইলটি বেশ পছন্দ করি তবে দুটি সম্ভাব্য সমস্যা রয়েছে। 1 : এটি পাইথন 3 এ কেবল কাজ করে; পাইথন 2 এ, এমন filterএকটি তালিকা প্রত্যাবর্তন করে যা সামঞ্জস্যপূর্ণ নয় next2 : এটির একটি সুনির্দিষ্ট ম্যাচ প্রয়োজন, অন্যথায় আপনি একটি StopIterationব্যতিক্রম পাবেন।
ফ্রিতেহিজ

1
1: আমি পাইথন সম্পর্কে সচেতন নই 2 আমি পাইথন ব্যবহার শুরু করার সময় পাইথন 3 ইতিমধ্যে উপলব্ধ ছিল available দুর্ভাগ্যক্রমে আমি পাইথন ২ এর স্পেসিফিকস সম্পর্কে নিখুঁত 2. আপনি যদি ব্যাতিক্রমের অনুরাগী না হন তবে আপনি পরবর্তী (..., কিছুই নয়) বা কিছু অন্যান্য ডিফল্ট মান ব্যবহার করতে পারেন। আমি এটিকে আমার কোডে মন্তব্য হিসাবে যুক্ত করেছি।
নিমা মৌসভী

@ ফ্রেথিবীস পয়েন্ট 2 আসলে ভাল হতে পারে। আমার যখন তালিকায় একটি নির্দিষ্ট বিষয় প্রয়োজন, দ্রুত ব্যর্থ হওয়া ভাল জিনিস
কেপ

7

একটি সাধারণ উদাহরণ : আমাদের নিম্নলিখিত অ্যারে রয়েছে

li = [{"id":1,"name":"ronaldo"},{"id":2,"name":"messi"}]

এখন, আমরা অ্যারেতে আইডিটি 1 এর সমান আইটেমটি খুঁজতে চাই

  1. nextতালিকা বোঝার সাথে পদ্ধতি ব্যবহার করুন
next(x for x in li if x["id"] == 1 )
  1. তালিকা বোঝার ব্যবহার করুন এবং প্রথম আইটেমটি ফিরুন
[x for x in li if x["id"] == 1 ][0]
  1. কাস্টম ফাংশন
def find(arr , id):
    for x in arr:
        if x["id"] == id:
            return x
find(li , 1)

উপরের সমস্ত পদ্ধতি আউটপুট {'id': 1, 'name': 'ronaldo'}


1

আমি কেবল একটি অনুরূপ সমস্যায় পড়েছি এবং তালিকার কোনও বস্তুর প্রয়োজনীয়তা পূরণ না হওয়ার ক্ষেত্রে একটি ছোট্ট অপ্টিমাইজেশন তৈরি করেছি ((আমার ব্যবহারের ক্ষেত্রে এটির ফলে পারফরম্যান্সের উন্নতি ঘটেছে):

টেস্ট_লিস্টের তালিকার পাশাপাশি, আমি একটি অতিরিক্ত সেট টেস্ট_ভ্যালু_সেট রাখি যা তালিকার মানগুলির সাথে আমার ফিল্টার করা দরকার to সুতরাং এখানে Agf এর সমাধানের অন্য অংশটি খুব দ্রুত হয়ে যায়।


1

আপনি এই মত কিছু করতে পারে

dict = [{
   "id": 1,
   "name": "Doom Hammer"
 },
 {
    "id": 2,
    "name": "Rings ov Saturn"
 }
]

for x in dict:
  if x["id"] == 2:
    print(x["name"])

লম্বা অ্যারে অবজেক্টগুলিতে সন্ধান করতে আমি কী ব্যবহার করি তা স্থায়ী।


এটি কীভাবে আলাদা তবে কী প্রশ্নকর্তা ইতিমধ্যে চেষ্টা করেছেন?
আনম শেরাজ

আমি প্রদর্শন করতে চেয়েছিলাম যে কীভাবে তিনি সহজ উপায়ে অবজেক্টের অবজেক্ট এবং অ্যারে পেতে পারেন।
ইলিউড

0

আপনি __eq__আপনার Testশ্রেণি এবং ব্যবহারের জন্য inঅপারেটর পদ্ধতির মাধ্যমে সমৃদ্ধ তুলনা প্রয়োগ করতে পারেন । এটি সর্বোত্তম একা উপায় কিনা তা নিশ্চিত নন তবে আপনি যদি অন্য কোথাও Testভিত্তিক উদাহরণগুলির তুলনা valueকরতে চান তবে এটি কার্যকর হতে পারে।

class Test:
    def __init__(self, value):
        self.value = value

    def __eq__(self, other):
        """To implement 'in' operator"""
        # Comparing with int (assuming "value" is int)
        if isinstance(other, int):
            return self.value == other
        # Comparing with another Test object
        elif isinstance(other, Test):
            return self.value == other.value

import random

value = 5

test_list = [Test(random.randint(0,100)) for x in range(1000)]

if value in test_list:
    print "i found it"

0

নীচের কোডের জন্য, xGen হ'ল এক অযৌক্তিক জেনারেটর এক্সপ্রেশন, ওয়াইফিল্ট একটি ফিল্টার অবজেক্ট। নোট করুন যে এক্সজেনের জন্য তালিকাটি শেষ হয়ে গেলে স্টিপ ইটরেটেশন নিক্ষেপ করার পরিবর্তে অতিরিক্ত কোনও প্যারামিটার ফিরে আসে না।

arr =((10,0), (11,1), (12,2), (13,2), (14,3))

value = 2
xGen = (x for x in arr if x[1] == value)
yFilt = filter(lambda x: x[1] == value, arr)
print(type(xGen))
print(type(yFilt))

for i in range(1,4):
    print('xGen: pass=',i,' result=',next(xGen,None))
    print('yFilt: pass=',i,' result=',next(yFilt))

আউটপুট:

<class 'generator'>
<class 'filter'>
xGen: pass= 1  result= (12, 2)
yFilt: pass= 1  result= (12, 2)
xGen: pass= 2  result= (13, 2)
yFilt: pass= 2  result= (13, 2)
xGen: pass= 3  result= None
Traceback (most recent call last):
  File "test.py", line 12, in <module>
    print('yFilt: pass=',i,' result=',next(yFilt))
StopIteration
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.