সেট পার্থক্য করার সময় শেষ উপাদানটিকে উপেক্ষা করার পাইথোনিক উপায়


11

ধরা যাক আমার দুটি set()এস আছে:

a = {('1', '2', '3', 'a'), ('1', '2', '4', 'a'), ('1', '2', '5', 'b')}
b = {('1', '2', '3', 'b'), ('1', '2', '4', 'b'), ('1', '2', '6', 'b')}

এখন, আমি যা করতে চাই তা হল সেট পার্থক্যটি সন্ধান করা b \ aকিন্তু প্রতিটি টিপল থেকে শেষ উপাদানটিকে উপেক্ষা করা। সুতরাং এটি ঠিক এমন কিছু করার মতো:

a = {('1', '2', '3'), ('1', '2', '4'), ('1', '2', '5')}
b = {('1', '2', '3'), ('1', '2', '4'), ('1', '2', '6')}

In[1]: b - a
Out[1]: {('1', '2', '6')}

প্রত্যাশিত আউটপুট:

b \ a = {('1', '2', '6', 'b')}

প্রতিটি সেটের উপর ম্যানুয়ালি পুনরাবৃত্তি না করে এবং প্রতিটিটির বিপরীতে পরীক্ষা না করে tuple[:3]কী অর্জন করার কোনও সুস্পষ্ট / পাইথোনিক উপায় আছে ?


3
আমার প্রাথমিক চিন্তাটি তাদের ক্লাস করা, তুলনা অপারেটরের সংজ্ঞা দেওয়া
কেনি অস্ট্রোম

2
সাবক্লাস setএবং পার্থক্য অপারেশন ওভাররাইট। বাক্সের বাইরে কোনও সমাধান নেই যা আমি জানি এবং আমি সন্দেহ করি যে এর একটি বিদ্যমান।
ইভ। কাউনিস

সেটের জন্য কোনও "কী = ..." বা এর মতো কিছু নেই (বাছাই করার জন্য (..))। টিপলগুলি হ্রাসযোগ্য এবং হ্যাশযোগ্য এবং তাদের হ্যাশের উপর ভিত্তি করে তুলনা করা হয়। একটি উপাদান অপসারণ হ্যাশ অকার্যকর হবে। তাই না - সম্ভব নয়। আপনার যদি মানটির প্রয়োজন না হয় তবে আপনি 3-অংশ সেট তৈরি করতে পারেন:aa = { t[:3] for t in a }
প্যাট্রিক আর্টনার

2
@ এ কে two two দুটি সেট এস এবং টি এর মধ্যে (সেট) পার্থক্যটি এস written টি লেখা হয়েছে, এবং এর অর্থ সেটটি এস এর উপাদানগুলি নিয়ে গঠিত যা টি এর উপাদান নয়: x∈S ∖ T⟺x∈S∧x∉T
গ্রেজডানু অ্যালেক্স।

সাবক্লাস tupleএবং পার্থক্য অপারেটরকে ওভাররাইড করে
পিনচিয়া

উত্তর:


10

টিপলের স্বাভাবিক হ্যাশিং আচরণকে ওভাররাইড করতে আপনি কীভাবে নিজের ক্লাস লিখতে পারেন তা এখানে:

a_data = [('1', '2', '3', 'a'), ('1', '2', '4', 'a'), ('1', '2', '5', 'b')]
b_data = [('1', '2', '3', 'b'), ('1', '2', '4', 'b'), ('1', '2', '6', 'b')]

class HashableIgnoresLastElement(tuple):
    def __eq__(self, other):
        return self[:-1] == other[:-1]

    def __hash__(self):
        return hash(self[:-1])

a = set(map(HashableIgnoresLastElement, a_data))
b = set(map(HashableIgnoresLastElement, b_data))

print(b - a)

আউটপুট সহ

{('1', '2', '6', 'b')}

টিপলসগুলির আচরণের সেটগুলি সংশোধন করতে, আমাদের টিউপলগুলি যেভাবে ধাবিত হয়েছে তা সংশোধন করতে হবে।

থেকে এখানে ,

কোনও বস্তুর হাশযোগ্য যদি এর হ্যাশ মান থাকে যা তার জীবদ্দশায় কখনই পরিবর্তিত হয় না (এটির জন্য একটি __hash__()পদ্ধতির প্রয়োজন) এবং অন্যান্য বস্তুর সাথে এটির তুলনা করা যেতে পারে (এটি একটি __eq__()পদ্ধতির প্রয়োজন)। সমান তুলনা করা যায় এমন হাস্যযোগ্য বস্তুর একই হ্যাশ মান থাকতে হবে।

হ্যাশাবিলিটি কোনও অভিধানকে কী এবং সেট সদস্য হিসাবে ব্যবহারযোগ্য করে তোলে, কারণ এই ডেটা স্ট্রাকচারগুলি হ্যাশ মানটি অভ্যন্তরীণভাবে ব্যবহার করে।

তাই যাতে হ্যাশ শেষ উপাদান উপেক্ষা করতে, আমরা dunder পদ্ধতি জমিদার আছে __eq__এবং __hash__উপযুক্তভাবে। এটি এত কঠিন হয়ে ওঠে না কারণ আমাদের যা করতে হবে তা হ'ল শেষ উপাদানটি কেটে ফেলা এবং তারপরে একটি সাধারণের উপযুক্ত পদ্ধতিগুলি অর্পণ করা tuple

আরও পড়া:


1
খুব ঝরঝরে! এটি কীভাবে কাজ করে আপনিও কিছুটা বর্ণনা করতে পারেন? যারা এই সমাধানটি পড়বেন তাদের পক্ষে এটি মূল্যবান হতে পারে।
গ্রেজডানু অ্যালেক্স।

@GrajdeanuAlex। আমি একটি সংক্ষিপ্ত ব্যাখ্যা যোগ করেছি :)। সত্যিই এটি কেবল বিট এবং অপারেটরের ওভারলোডিংয়ের টুকরো এবং পাইথনে হ্যাশিং কীভাবে কাজ করে তা একত্রিত করে।
ইজাক ভ্যান ডোনজেন

2

এখানে সেটগুলির পরিবর্তে তালিকার সংজ্ঞা aএবং bতালিকাগুলির সাথে সম্পর্কিত একটি পদ্ধতির কারণ এটি আমার কাছে মনে হয় যে সর্বাধিক সরাসরি সমাধানটি সূচকে বোঝায় b:

a = [('1', '2', '3', 'a'), ('1', '2', '4', 'a'), ('1', '2', '5', 'b')]
b = [('1', '2', '3', 'b'), ('1', '2', '4', 'b'), ('1', '2', '6', 'b')]

# reconstruct the sets of tuples removing the last elements
a_ = {tuple(t) for *t, _ in a}
b_ = [tuple(t) for *t, _ in b]

# index b based on whether an element in a_
[b[ix] for ix, j in enumerate(b_) if j not in a_]
# [('1', '2', '6', 'b')]

1
এটি যদি আমি ভুল করছি না তবে এটি হ'ল (এন), যেহেতু আমি অনুসন্ধানের জন্য একটি সেট ব্যবহার করি। যদিও আমি মনে করি ইজাক ভ্যান ডনজেনের উত্তরটি অনেক বেশি মার্জিত @ কনরাড
ইয়াতু

1
আপনি সম্পূর্ণরূপে ঠিক আছেন, একটি তালিকা (এবং গণনার উপরে) ব্যবহারের ফলে আমাকে ছুঁড়ে ফেলেছে তবে অবশ্যই একটি সেট পার্থক্যও প্রথম সেটটিতে পুনরাবৃত্তি হওয়া দরকার।
কনরাড রুডল্ফ

1

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

class thing:
    def __init__(self, a, b, c, d):
        self.a, self.b, self.c, self.d = a, b, c, d

    def __repr__(self):
        return (str((self.a, self.b, self.c, self.d)))

    def __hash__(self):
        return hash((self.a, self.b, self.c))

    def __eq__(self, other):
        return self.a == other.a and self.b == other.b and self.c == other.c       

a = {thing('1', '2', '3', 'a'), thing('1', '2', '4', 'a'), thing('1', '2', '5', 'b')}
b = {thing('1', '2', '3', 'b'), thing('1', '2', '4', 'b'), thing('1', '2', '6', 'b')}
print (b - a)

'(' 1 ',' 2 ',' 6 ',' বি ')}


3
আপনি সংজ্ঞায়িত __repr__এবং __hash__tuples পদে, কিন্তু না __eq__। এখানেও টিপলস ব্যবহার করা কি খাটো হবে না? আসলে, আপনি __hash__কোডটি আরও সংক্ষিপ্ত করতে এখানে এবং স্লাইসিং ব্যবহার করতে পারেন ।
কনরাড রুডলফ

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