পাইথনের একটি তালিকায় কিছু (না) রয়েছে কিনা তা পরীক্ষা করে দেখুন


314

পাইথনে আমার টিপলগুলির একটি তালিকা রয়েছে এবং আমার শর্তসাপেক্ষ রয়েছে যেখানে আমি টিপল তালিকায় না থাকলে কেবল শাখাটি নিতে চাই (যদি এটি তালিকায় থাকে তবে আমি যদি শাখাটি নিতে চাই না)

if curr_x -1 > 0 and (curr_x-1 , curr_y) not in myList: 

    # Do Something

যদিও এটি আমার পক্ষে সত্যিই কাজ করছে না। আমি কি ভুল করেছি?


1
নোট করুন 3 -1 > 0 and (4-1 , 5) not in []Trueতাই ত্রুটি অপারেটর নজরে নয়।
ড্যান ডি

6
"সত্যই আমার পক্ষে কাজ না করা" বলতে কী বোঝ? তুমি কী আশা করবে? আসলে কি হয়? সঠিক তালিকা বিষয়বস্তু সমস্যা ট্রিগার করে?
কার্ল নচেটেল

কেন চেষ্টা করবেন না myList.count((curr_x, curr_y)), যদি (curr_x, curr_y)না থাকে myListতবে ফলাফলটি হবে0
লিটলিটলকিউ


2
এই "আমার কোডটি সত্যই আমার পক্ষে কাজ করে না" প্রশ্নটি কীভাবে 297 টি আপত্তি পেয়েছে? দয়া করে আমাদের একটি ন্যূনতম প্রজননযোগ্য উদাহরণ দিন
16

উত্তর:


502

বাগটি সম্ভবত আপনার কোডের অন্য কোনও জায়গায় রয়েছে কারণ এটি ঠিকঠাক কাজ করা উচিত:

>>> 3 not in [2, 3, 4]
False
>>> 3 not in [4, 5, 6]
True

বা টিপলস সহ:

>>> (2, 3) not in [(2, 3), (5, 6), (9, 1)]
False
>>> (2, 3) not in [(2, 7), (7, 3), "hi"]
True

11
@ জ্যাক: আপনি যদি এই সম্পর্কে না জানতেন তবে আপনি ঠিক করতে পারতেনif not ELEMENT in COLLECTION:
নিনজেকেকো

@ নিনজাগেকো: ধারক প্রকারের উপর নির্ভর করে যা কম দক্ষ বা এমনকি ভুল হতে পারে। উদাহরণস্বরূপ ব্লুম ফিল্টারগুলি দেখুন
orlp

14
@nightcracker এর কোনও মানে যেমন তোলে A not in Bকরছেন কমে যাবে not B.__contains__(A)যা কি হিসাবে একই not A in Bকমে যাবে যা হয় not B.__contains__(A)
ড্যান ডি

1
ওহ বাহ, আমি পাইথনের শপথ করতে পারতাম এরকম কিছু ছিল __notcontains__। আমি দুঃখিত, তারপরে আমি যা বলেছি তা কেবল বুলডশিট।
orlp

2
@ std''OrgnlDave একমাত্র উপায় যে ঘটতে পারে তা হ'ল যদি notএর চেয়ে বেশি অগ্রাধিকার থাকে inযা না করে। ast.dump(ast.parse("not A in B").body[0])যার ফলাফলটি বিবেচনা করুন ফলাফলগুলিতে "Expr(value=UnaryOp(op=Not(), operand=Compare(left=Name(id='A', ctx=Load()), ops=[In()], comparators=[Name(id='B', ctx=Load())])))"যদি notএটিকে শক্ত করে দলবদ্ধ করা হয় তবে ফলাফলটি "Expr(value=Compare(left=UnaryOp(op=Not(), operand=Name(id='A', ctx=Load())), ops=[In()], comparators=[Name(id='B', ctx=Load())]))"পার্স হওয়ার ফলাফলটি প্রত্যাশা করে "(not A) in B"
ড্যান ডি

20

পাইথনের তালিকায় কিছু (না) রয়েছে কিনা তা আমি কীভাবে পরীক্ষা করব?

সবচেয়ে সস্তা এবং সর্বাধিক পঠনযোগ্য সমাধানটি inঅপারেটরটি (বা আপনার নির্দিষ্ট ক্ষেত্রে, not in) ব্যবহার করছে। নথিতে উল্লিখিত হিসাবে,

অপারেটরদের inএবং not inসদস্যতার জন্য পরীক্ষা। x in sএর সদস্য Trueকিনা xতা মূল্যায়ন করে sএবং Falseঅন্যথায়। x not in sপ্রত্যাখ্যান ফিরিয়ে দেয় x in s

উপরন্তু,

অপারেটরটির not inবিপরীত সত্য মানটি সংজ্ঞায়িত করা হয় in

y not in xযৌক্তিকভাবে একই not y in x

এখানে কিছু উদাহরণ আছে:

'a' in [1, 2, 3]
# False

'c' in ['a', 'b', 'c']
# True

'a' not in [1, 2, 3]
# True

'c' not in ['a', 'b', 'c']
# False

এটি টিউপলসের সাথেও কাজ করে, যেহেতু টিপলগুলি হ্যাশেবল হয় (যে তারাও অপরিবর্তনীয় এই ফলস্বরূপ):

(1, 2) in [(3, 4), (1, 2)]
#  True

আরএইচএসে থাকা অবজেক্টটি যদি কোনও __contains__()পদ্ধতি সংজ্ঞায়িত করে তবে ডকসের তুলনা বিভাগের inশেষ অনুচ্ছেদে উল্লিখিত হিসাবে এটি অভ্যন্তরীণভাবে এটিকে ডাকবে ।

... inএবং not in, এমন ধরণের দ্বারা সমর্থিত যা পুনরাবৃত্তিযোগ্য বা __contains__()পদ্ধতিটি কার্যকর করে । উদাহরণস্বরূপ, আপনি এটি করতে পারেন (তবে হওয়া উচিত নয়):

[3, 2, 1].__contains__(1)
# True

inশর্ট সার্কিট, সুতরাং যদি আপনার উপাদানটি তালিকার শুরুতে থাকে তবে inদ্রুত মূল্যায়ন করুন:

lst = list(range(10001))
%timeit 1 in lst
%timeit 10000 in lst  # Expected to take longer time.

68.9 ns ± 0.613 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
178 µs ± 5.01 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

আপনি যদি তালিকায় কোনও আইটেম আছে কিনা তা পরীক্ষা করে দেখার চেয়ে আরও কিছু করতে চান তবে বিকল্পগুলি রয়েছে:

  • list.indexকোনও আইটেমের সূচি পুনরুদ্ধার করতে ব্যবহার করা যেতে পারে। যদি সেই উপাদানটির অস্তিত্ব না থাকে তবে একটি ValueErrorউত্থাপিত হয়।
  • list.count আপনি যদি ঘটনাগুলি গণনা করতে চান তবে ব্যবহার করা যেতে পারে।

এক্সওয়াই সমস্যা: আপনি কি বিবেচনা করেছেন set?

নিজেকে এই প্রশ্নগুলি জিজ্ঞাসা করুন:

  • তালিকার কোনও আইটেম একাধিকবার রয়েছে কিনা তা আপনার চেক করা দরকার?
  • এই চেকটি কোনও লুপের ভিতরে করা হয়, বা কোনও ফাংশন বারবার বলা হয়?
  • আপনি আপনার তালিকায় যে আইটেমগুলি সংরক্ষণ করছেন তা কি হ্যাশেবল? IOW, আপনি hashতাদের সাথে ফোন করতে পারেন ?

আপনি যদি এই প্রশ্নের উত্তর "হ্যাঁ" দেন তবে আপনার setপরিবর্তে এটি ব্যবহার করা উচিত । ও- inতে একটি সদস্যপদ পরীক্ষা listহ'ল ও (এন) সময়ের জটিলতা। এর অর্থ হ'ল অজগরকে আপনার তালিকার একটি লিনিয়ার স্ক্যান করতে হবে, প্রতিটি উপাদানটিতে গিয়ে অনুসন্ধান আইটেমের সাথে তুলনা করতে হবে। আপনি যদি বারবার এটি করছেন, বা তালিকাগুলি বড় হয় তবে এই অপারেশনটিতে একটি ওভারহেড লাগবে।

setঅন্যদিকে অবজেক্টগুলি স্থির সময়ের সদস্যপদ চেক করার জন্য তাদের মানগুলি হ্যাশ করে। চেকটি ব্যবহার করেও করা হয় in:

1 in {1, 2, 3} 
# True

'a' not in {'a', 'b', 'c'}
# False

(1, 2) in {('a', 'c'), (1, 2)}
# True

আপনি যদি দুর্ভাগ্যজনক হন যে আপনি যে উপাদানটি অনুসন্ধান করছেন / অনুসন্ধান করছেন না তা আপনার তালিকার শেষে রয়েছে, অজগরটি তালিকাটি শেষ পর্যন্ত স্ক্যান করবে have এটি নীচের সময়গুলি থেকে স্পষ্ট:

l = list(range(100001))
s = set(l)

%timeit 100000 in l
%timeit 100000 in s

2.58 ms ± 58.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
101 ns ± 9.53 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

অনুস্মারক হিসাবে, আপনি যতক্ষণ উপাদান সংরক্ষণ করছেন এবং সন্ধান করছেন ততক্ষণ এটি উপযুক্ত বিকল্প। আইওডাব্লু, তাদের হয় হয় অপরিবর্তনীয় প্রকারের, বা বস্তু যা বাস্তবায়ন করে __hash__


2
সেটগুলি সর্বদা একটি বিকল্প হয় না (উদাহরণস্বরূপ, যখন পরিবর্তনীয় আইটেমগুলির একটি তালিকা থাকে)। বড় সংগ্রহের জন্য: অনুসন্ধানের জন্য সেটটি তৈরি করা ও (এন) যেকোন সময় এবং আপনার মেমরির ব্যবহার দ্বিগুণ করতে পারে। আপনার যদি ইতিমধ্যে চারপাশে অনুসন্ধান না থাকে তবে এটি তৈরি / বজায় রাখা সর্বদা সেরা পছন্দ নয়।
উইম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.