উত্তর:
এটি আপনি যা চান তা করে এবং প্রায় সব ক্ষেত্রেই কাজ করবে:
>>> all(x in ['b', 'a', 'foo', 'bar'] for x in ['a', 'b'])
True
এক্সপ্রেশনটি 'a','b' in ['b', 'a', 'foo', 'bar']প্রত্যাশার মতো কাজ করে না কারণ পাইথন এটিকে একটি টিপল হিসাবে ব্যাখ্যা করে:
>>> 'a', 'b'
('a', 'b')
>>> 'a', 5 + 2
('a', 7)
>>> 'a', 'x' in 'xerxes'
('a', True)
এই পরীক্ষাটি সম্পাদন করার অন্যান্য উপায় রয়েছে তবে তারা বিভিন্ন ধরণের ইনপুটগুলির জন্য কাজ করবে না। কবি যেমন উল্লেখ করেছেন, আপনি সেটগুলি ব্যবহার করে এই সমস্যাটি সমাধান করতে পারেন ...
>>> set(['a', 'b']).issubset(set(['a', 'b', 'foo', 'bar']))
True
>>> {'a', 'b'} <= {'a', 'b', 'foo', 'bar'}
True
... কখনো কখনো:
>>> {'a', ['b']} <= {'a', ['b'], 'foo', 'bar'}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
সেটগুলি কেবলমাত্র হ্যাশযোগ্য উপাদানগুলির সাহায্যে তৈরি করা যেতে পারে। তবে জেনারেটর এক্সপ্রেশন all(x in container for x in items)প্রায় কোনও ধারক প্রকারকে পরিচালনা করতে পারে। একমাত্র প্রয়োজন হ'ল containerপুনরায় পুনরাবৃত্তিযোগ্য (অর্থাত্ জেনারেটর নয়)। itemsআদৌ যে কোনও পুনরাবৃত্ত হতে পারে।
>>> container = [['b'], 'a', 'foo', 'bar']
>>> items = (i for i in ('a', ['b']))
>>> all(x in [['b'], 'a', 'foo', 'bar'] for x in items)
True
অনেক ক্ষেত্রে সাবসেট পরীক্ষাটি দ্রুততর হবে all, তবে পার্থক্যটি চটজলদি নয় - যখন প্রশ্নটি অপ্রাসঙ্গিক হয় তবে সেটগুলি কোনও বিকল্প নয়। কেবলমাত্র পরীক্ষার উদ্দেশ্যে তালিকাগুলি সেটগুলিতে রূপান্তর করা সর্বদা সমস্যার জন্য উপযুক্ত হবে না। এবং জেনারেটরগুলিকে সেটে রূপান্তর করা কখনও কখনও অবিশ্বাস্যরূপে অপব্যয়যোগ্য হতে পারে, প্রস্থের বহু আদেশের মাধ্যমে প্রোগ্রামকে ধীর করে দেয়।
উদাহরণের জন্য কয়েকটি মানদণ্ড এখানে দেওয়া হল। উভয় containerএবং itemsতুলনামূলকভাবে ছোট হলে সবচেয়ে বড় পার্থক্য আসে । সেক্ষেত্রে সাবসেট পদ্ধতির দ্রুততার পরিমাণ প্রায় দ্রুত অর্ডার করা:
>>> smallset = set(range(10))
>>> smallsubset = set(range(5))
>>> %timeit smallset >= smallsubset
110 ns ± 0.702 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
>>> %timeit all(x in smallset for x in smallsubset)
951 ns ± 11.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
এটি একটি বড় পার্থক্য মত দেখাচ্ছে। তবে যতক্ষণ না containerসেট রয়েছে, allএখনও বৃহত্তর স্কেলগুলিতে পুরোপুরি ব্যবহারযোগ্য:
>>> bigset = set(range(100000))
>>> bigsubset = set(range(50000))
>>> %timeit bigset >= bigsubset
1.14 ms ± 13.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
>>> %timeit all(x in bigset for x in bigsubset)
5.96 ms ± 37 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
সাবসেট পরীক্ষার ব্যবহার এখনও দ্রুত, তবে এই স্কেলটিতে কেবল প্রায় 5x by পাইথনের দ্রুত- cব্যাক প্রয়োগের কারণে গতি বাড়ানো হয় setতবে উভয় ক্ষেত্রেই মৌলিক অ্যালগরিদম একই is
যদি আপনি itemsইতিমধ্যে অন্য কারণে কোনও তালিকায় সঞ্চিত থাকেন তবে আপনাকে সাবসেট পরীক্ষার পদ্ধতির ব্যবহারের আগে সেগুলিকে একটি সেটে রূপান্তর করতে হবে। তারপরে স্পিডআপটি প্রায় 2.5x এ নেমে যায়:
>>> %timeit bigset >= set(bigsubseq)
2.1 ms ± 49.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
এবং যদি আপনার containerক্রম হয় এবং প্রথমে রূপান্তরিত হওয়া দরকার তবে গতিবেগ আরও ছোট হয়:
>>> %timeit set(bigseq) >= set(bigsubseq)
4.36 ms ± 31.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
কেবলমাত্র যখন আমরা containerক্রম হিসাবে চলে যাই তখনই কেবল আমরা বিপর্যয়করভাবে ধীর ফলাফল পাই :
>>> %timeit all(x in bigseq for x in bigsubseq)
184 ms ± 994 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
এবং অবশ্যই, আমরা কেবল যদি এটি করা প্রয়োজন। যদি সমস্ত আইটেম bigseqহ্যাশযোগ্য হয়, তবে আমরা পরিবর্তে এটি করব:
>>> %timeit bigset = set(bigseq); all(x in bigset for x in bigsubseq)
7.24 ms ± 78 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
এটি বিকল্পটির চেয়ে মাত্র 1.66x দ্রুত ( set(bigseq) >= set(bigsubseq)উপরে উপরে 4.36 এ সময়সীমা)।
সুতরাং সাবসেট টেস্টিংটি সাধারণত দ্রুত হয়, তবে অবিশ্বাস্য ব্যবধানের দ্বারা নয়। অন্যদিকে, আসুন কখন allদ্রুত হয় তা দেখি । যদি itemsদশ-মিলিয়ন মান দীর্ঘ হয় এবং এর মধ্যে মান না থাকে তবে containerকী হতে পারে ?
>>> %timeit hugeiter = (x * 10 for bss in [bigsubseq] * 2000 for x in bss); set(bigset) >= set(hugeiter)
13.1 s ± 167 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
>>> %timeit hugeiter = (x * 10 for bss in [bigsubseq] * 2000 for x in bss); all(x in bigset for x in hugeiter)
2.33 ms ± 65.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
জেনারেটরটিকে একটি সেটে রূপান্তর করা এই ক্ষেত্রে অবিশ্বাস্যরকম অপব্যয় হিসাবে প্রমাণিত হয়। setকন্সট্রাকটর সমগ্র জেনারেটরের গ্রাস হয়েছে। তবে সংক্ষিপ্তসার্চিয়টিং আচরণটি allনিশ্চিত করে যে জেনারেটরের কেবলমাত্র একটি ছোট অংশ গ্রাস করা প্রয়োজন, তাই এটি চার মাত্রার চারটি অর্ডার দ্বারা সাবসেট পরীক্ষার চেয়ে দ্রুত ।
স্বীকৃতি স্বরূপ এটি চরম উদাহরণ example তবে এটি যেমন দেখায়, আপনি ধরে নিতে পারবেন না যে একটি ক্ষেত্রে বা অন্যটি সব ক্ষেত্রেই দ্রুত হবে।
বেশিরভাগ সময়, containerএকটি সেটে রূপান্তর করা উপযুক্ত, কমপক্ষে যদি এর সমস্ত উপাদানগুলি হ্যাশযোগ্য হয়। কারণ inসেটের জন্য ও (1) হয়, যখন inসিকোয়েন্সগুলির জন্য ও (এন) হয়।
অন্যদিকে, সাবসেট টেস্টিং ব্যবহার করা কখনও কখনও কেবল এটির পক্ষে উপযুক্ত। আপনার পরীক্ষার আইটেমগুলি ইতিমধ্যে একটি সেটে সঞ্চিত থাকলে অবশ্যই এটি করুন। অন্যথায়, allএটি কেবল সামান্য ধীর এবং এ জন্য কোনও অতিরিক্ত স্টোরেজ প্রয়োজন হয় না। এটি আইটেমগুলির বৃহত জেনারেটরগুলির সাথেও ব্যবহার করা যেতে পারে এবং কখনও কখনও সে ক্ষেত্রে একটি বিশাল গতিবেগ সরবরাহ করে।
এটি করার আরেকটি উপায়:
>>> set(['a','b']).issubset( ['b','a','foo','bar'] )
True
{'a', 'b'} <= {'b','a','foo','bar'}
আপনি যদি আপনার সমস্ত ইনপুট ম্যাচ চেক করতে চান ,
>>> all(x in ['b', 'a', 'foo', 'bar'] for x in ['a', 'b'])
যদি আপনি কমপক্ষে একটি ম্যাচ পরীক্ষা করতে চান ,
>>> any(x in ['b', 'a', 'foo', 'bar'] for x in ['a', 'b'])
পাইথন পার্সার সেই বিবৃতিটিকে একটি টিউপল হিসাবে মূল্যায়ন করে, যেখানে প্রথম মানটি ছিল 'a'এবং দ্বিতীয় মানটি হল অভিব্যক্তি 'b' in ['b', 'a', 'foo', 'bar'](যা মূল্যায়ন করে True)।
আপনি একটি সাধারণ ফাংশন লিখতে পারেন যা করতে চান তা করুন, যদিও:
def all_in(candidates, sequence):
for element in candidates:
if element not in sequence:
return False
return True
এবং এটিকে কল করুন:
>>> all_in(('a', 'b'), ['b', 'a', 'foo', 'bar'])
True
[x for x in ['a','b'] if x in ['b', 'a', 'foo', 'bar']]
আমি নির্বাচিত উত্তরের চেয়ে এটি ভাল বলে মনে করার কারণটি হ'ল সত্যই আপনাকে 'সমস্ত ()' ফাংশন কল করার দরকার নেই। খালি তালিকা যদি বিবৃতিতে ভুতে মূল্যায়ন করে, খালি খালি তালিকাটি সত্যকে মূল্যায়ন করে।
if [x for x in ['a','b'] if x in ['b', 'a', 'foo', 'bar']]:
...Do something...
উদাহরণ:
>>> [x for x in ['a','b'] if x in ['b', 'a', 'foo', 'bar']]
['a', 'b']
>>> [x for x in ['G','F'] if x in ['b', 'a', 'foo', 'bar']]
[]
এখানে উপস্থাপন করা উভয় উত্তর পুনরাবৃত্তি উপাদানগুলি পরিচালনা করবে না। উদাহরণস্বরূপ, আপনি যদি [১,২,২] টি [1,2,3,4] এর একটি সাবলিস্ট কিনা তা পরীক্ষা করে দেখেন তবে উভয়ই সত্য আসবে। আপনি যা করতে চান তা সেটাই হতে পারে তবে আমি কেবল পরিষ্কার করতে চেয়েছিলাম। আপনি যদি [1,2,3,4] এর মধ্যে [1,2,2] এর জন্য মিথ্যা ফিরতে চান তবে আপনাকে উভয় তালিকাগুলি বাছাই করতে হবে এবং প্রতিটি তালিকার চলমান সূচী সহ প্রতিটি আইটেম পরীক্ষা করতে হবে। লুপের জন্য আরও কিছুটা জটিল।
ল্যাম্বডাস ছাড়া আপনি কীভাবে অজগর হতে পারেন! .. গুরুত্ব সহকারে নেওয়া হবে না .. তবে এইভাবে কাজ করে:
orig_array = [ ..... ]
test_array = [ ... ]
filter(lambda x:x in test_array, orig_array) == test_array
বাদ শেষ অংশ আপনি পরীক্ষা করতে চান তাহলে কোন মূল্যবোধের অ্যারের মধ্যে আছেন:
filter(lambda x:x in test_array, orig_array)
filterজেনারেটর হিসাবে অভিযুক্ত হিসাবে কাজ করবে না । আপনি listযদি এটির এমন একটি ফলাফল পেতে চান যা আপনি ==বুলিয়ান প্রসঙ্গে বা পরীক্ষা করতে পারেন (এটি খালি কিনা তা দেখতে) আপনি আসলে এটি মুড়ে ফেলতে হবে। একটি তালিকা ধী বা জেনারেটরের অভিব্যক্তি ব্যবহার anyবা allবাঞ্ছনীয়।
set(['a', 'b']) <= set(['b','a','foo','bar'])একই জিনিসটির বানান করার অন্য একটি উপায় এবং এটি "ম্যাথিয়ার" দেখাচ্ছে।