একটি স্বেচ্ছাসেবী শর্ত ফাংশন অনুসারে একটি অভিধান কীভাবে ফিল্টার করবেন?


212

আমার কাছে পয়েন্টগুলির একটি অভিধান রয়েছে, বলুন:

>>> points={'a':(3,4), 'b':(1,2), 'c':(5,5), 'd':(3,3)}

আমি সমস্ত পয়েন্টের সাথে একটি নতুন অভিধান তৈরি করতে চাই যার x এবং y মান 5 এর চেয়ে কম, অর্থাৎ 'a', 'b' এবং 'd' পয়েন্ট করুন।

বই অনুসারে , প্রতিটি অভিধানে items()ফাংশন রয়েছে, যা (key, pair) tuple এর একটি তালিকা ফেরত দেয় :

>>> points.items()
[('a', (3, 4)), ('c', (5, 5)), ('b', (1, 2)), ('d', (3, 3))]

সুতরাং আমি এটি লিখেছি:

>>> for item in [i for i in points.items() if i[1][0]<5 and i[1][1]<5]:
...     points_small[item[0]]=item[1]
...
>>> points_small
{'a': (3, 4), 'b': (1, 2), 'd': (3, 3)}

আরও কি মার্জিত উপায় আছে? আমি আশা করছিলাম পাইথনটি কিছু দুর্দান্ত-দুর্দান্ত dictionary.filter(f)কাজ করবে ...


উত্তর:


427

আজকাল, পাইথন ২.7 এবং তারপরে আপনি একটি ডিক বোঝাপড়া ব্যবহার করতে পারেন:

{k: v for k, v in points.iteritems() if v[0] < 5 and v[1] < 5}

এবং পাইথন 3 এ:

{k: v for k, v in points.items() if v[0] < 5 and v[1] < 5}

15
ভোট দিন! এটি মার্টেলিসের বেশি সাধারণ পদ্ধতির চেয়ে দ্বিগুণেরও বেশি দ্রুত। মনে রাখবেন আপনি মতামতও ব্যবহার করতে পারেন (পুনরাবৃত্তির মতো, তারা ডিক আইটেমের অনুলিপি নয়): [k: v এর জন্য, পয়েন্টে ভিউ (ভিউ) যদি ভি [0] <5 এবং ভি [1] < 5}
ডরভাক

5
এবং এখানে ফাংশন কল ডিক () কেন কনস্ট্রাক্টর / আক্ষরিক সিনট্যাক্সের চেয়ে ধীর is} ডঘেলহেলম্যানn.com/2012/11/…
ডোরভাক

1
মনে রাখবেন যে iteritemsপাইথন 3 এ সরানো হয়েছিল তবে আপনি itemsপরিবর্তে এটি ব্যবহার করতে পারেন । এটি iteritemsপুরানো সংস্করণগুলিতে কাজ করার আচরণ করে beha
এলিয়াস জামারিয়া

1
@ দাতানোভিস আমি নিশ্চিত যে একজন এটি করতে পেরেছেন। আরও দরকারী উত্তর পাওয়ার জন্য যথেষ্ট পরিমাণে একটি নতুন প্রশ্নও খুলতে পারে;)
থমাস

1
একজন সীমিত প্রতিক্রিয়া সহ একটি প্রশ্ন খোলেন, এইভাবে একটি আরও ভাল বোঝার জন্য একজন যতটা সম্ভব প্রশ্ন পড়ার আশ্রয় নিয়েছেন। দেখে আরো একটি বুদ্ধিমান এক এবং এইভাবে বেশী ঘিলু বাছাই অব্যাহত;) আমার প্রশ্ন: stackoverflow.com/questions/50104127/...
Datanovice

110
dict((k, v) for k, v in points.items() if all(x < 5 for x in v))

আপনি পাইথন ২ এ থাকলে .iteritems()পরিবর্তে কল করতে বেছে নিতে পারেন .items()এবং এতে প্রচুর এন্ট্রি pointsথাকতে পারে ।

all(x < 5 for x in v)আপনি যদি নিশ্চিতভাবে জানেন যে প্রতিটি পয়েন্ট সর্বদা 2D হবে (তবে সেই ক্ষেত্রে আপনি একটির সাথে একই বাধা প্রকাশ করতে পারেন and) তবে এটি কার্যকর হবে ;-)।


21
points_small = dict(filter(lambda (a,(b,c)): b<5 and c < 5, points.items()))

1
পাইথন 2-এ আইটেম () এর পরিবর্তে iteritems () ব্যবহার করুন
Regisz

2
অজগর 3.5 তে, এটি একটি ত্রুটি ফিরিয়ে দেয়: পয়েন্ট_স্মাল = ডিক (ফিল্টার (ল্যাম্বদা (ক, (খ, সি)): বি <5 এবং সি <5, পয়েন্টস.ইটেমস ())
nt

আমি মনে করি এটি অজগর 3
ম্যাটানস্টার

15
>>> points = {'a': (3, 4), 'c': (5, 5), 'b': (1, 2), 'd': (3, 3)}
>>> dict(filter(lambda x: (x[1][0], x[1][1]) < (5, 5), points.items()))

{'a': (3, 4), 'b': (1, 2), 'd': (3, 3)}

3
দুর্দান্ত! এটি পিআই 3 উল্লেখ করার মতো, যেহেতু ল্যাম্বদা আর টিউপল যুক্তিটি আনপ্যাক করতে পারে না (
পিপি

আপনি ডিক্সোগ্রাফিকভাবে টিপলগুলি তুলনা করেন, যা ওপি প্রয়োজনীয় নয়। আপনার ক্ষেত্রে পয়েন্টটি (3, 10)পরীক্ষায় উত্তীর্ণ হবে: (3, 10) < (5, 5)এটি সত্য, তবে এটি ভুল ( yপাশাপাশি 5 এর চেয়ে কম হওয়াও উচিত)।
দিমিত্রি_রোমানভ


7

আমি মনে করি যে অ্যালেক্স মার্তেলির উত্তর অবশ্যই এটি করার জন্য সবচেয়ে মার্জিত উপায়, তবে কেবল dictionary.filter(f)একটি পাইথোনিক পদ্ধতিতে একটি দুর্দান্ত দুর্দান্ত পদ্ধতির জন্য আপনার ইচ্ছা পূরণ করার উপায় যুক্ত করতে চেয়েছিলেন :

class FilterDict(dict):
    def __init__(self, input_dict):
        for key, value in input_dict.iteritems():
            self[key] = value
    def filter(self, criteria):
        for key, value in self.items():
            if (criteria(value)):
                self.pop(key)

my_dict = FilterDict( {'a':(3,4), 'b':(1,2), 'c':(5,5), 'd':(3,3)} )
my_dict.filter(lambda x: x[0] < 5 and x[1] < 5)

মূলত আমরা একটি বর্গ তৈরি করি যা উত্তরাধিকার সূত্রে প্রাপ্ত হয় dictতবে ফিল্টার পদ্ধতিটি যুক্ত করে। .items()ফিল্টারিংয়ের জন্য আমাদের ব্যবহার করা দরকার , কারণ .iteritems()ধ্বংসাত্মকভাবে পুনরাবৃত্তি করার সময় ব্যতিক্রম ঘটবে।


+1 ধন্যবাদ, মার্জিত কোড। আমি সত্যিই মনে করি এটি স্ট্যান্ডার্ড অভিধানের একটি অংশ হওয়া উচিত।
আদম মাতান

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.