পাইথন না হলে == বনাম যদি! =


183

এই দুটি লাইনের কোডের মধ্যে পার্থক্য কী:

if not x == 'val':

এবং

if x != 'val':

একজনের কি অন্যের চেয়ে বেশি দক্ষ?

এটি ব্যবহার করা ভাল

if x == 'val':
    pass
else:

101
আপনি যেটি পড়তে পারবেন এটি তত ভাল, আমি সন্দেহ করি আপনার প্রোগ্রামের বাধা এখানে আসবে
টমাস আইয়ুব

1
এই প্রশ্নটি আমাকে "তালিকার সাথে নয়" এবং "তালিকায় এক্স নয়" ক্ষেত্রে আগ্রহী
সামিথিংসামিংথিং

5
@ সোনিথিংসমিংথিং এগুলি একইভাবে ব্যাখ্যা করা হয়।
jonrsharpe

4
আমার উপরে মন্তব্যের জন্য রেফারেন্স @SomethingSomething stackoverflow.com/q/8738388/3001761
jonrsharpe

1
@ সামমথিংসমিংথিং those এটির ক্ষেত্রেও একই; সিনট্যাক্সটি কীভাবে ব্যাখ্যা করা হয়, এটি দুটি ক্রিয়াকলাপ কী তা বিবেচ্য নয়।
jonrsharpe

উত্তর:


229

disদুটি সংস্করণের জন্য উত্পন্ন বাইটকোডটি দেখতে ব্যবহার করে :

not ==

  4           0 LOAD_FAST                0 (foo)
              3 LOAD_FAST                1 (bar)
              6 COMPARE_OP               2 (==)
              9 UNARY_NOT           
             10 RETURN_VALUE   

!=

  4           0 LOAD_FAST                0 (foo)
              3 LOAD_FAST                1 (bar)
              6 COMPARE_OP               3 (!=)
              9 RETURN_VALUE   

পরেরটির অপারেশন কম রয়েছে এবং তাই এটি সম্ভবত আরও বেশি দক্ষ হওয়ার সম্ভাবনা রয়েছে।


এটা নির্দিষ্ট করা হয় commments মধ্যে (ধন্যবাদ, @Quincunx ) যে যেখানে আপনি if foo != barবনাম if not foo == barঅপারেশনের সংখ্যা ঠিক একই, এটা ঠিক যে COMPARE_OPপরিবর্তন এবং POP_JUMP_IF_TRUEপরিবর্তন করা POP_JUMP_IF_FALSE:

not ==:

  2           0 LOAD_FAST                0 (foo)
              3 LOAD_FAST                1 (bar)
              6 COMPARE_OP               2 (==)
              9 POP_JUMP_IF_TRUE        16

!=

  2           0 LOAD_FAST                0 (foo)
              3 LOAD_FAST                1 (bar)
              6 COMPARE_OP               3 (!=)
              9 POP_JUMP_IF_FALSE       16

এক্ষেত্রে, প্রতিটি তুলনার জন্য প্রয়োজনীয় কাজের পরিমাণে পার্থক্য না থাকলে আপনি কোনও পারফরম্যান্সের পার্থক্য দেখতে পাচ্ছেন না।


তবে নোট করুন যে দুটি সংস্করণ সর্বদা যুক্তিযুক্তভাবে অভিন্ন হবে না , কারণ এটি প্রশ্নে থাকা বস্তুর প্রয়োগ __eq__ও বাস্তবায়নের উপর নির্ভর করবে __ne__ডেটা মডেল ডকুমেন্টেশন প্রতি :

তুলনা অপারেটরদের মধ্যে কোনও অন্তর্নিহিত সম্পর্ক নেই। এর সত্যটি মিথ্যা x==yবলে বোঝায় না x!=y

উদাহরণ স্বরূপ:

>>> class Dummy(object):
    def __eq__(self, other):
        return True
    def __ne__(self, other):
        return True


>>> not Dummy() == Dummy()
False
>>> Dummy() != Dummy()
True

অবশেষে, এবং সম্ভবত সবচেয়ে গুরুত্বপূর্ণ: সাধারণ, যেখানে দুই হয় কথাটি অভিন্ন, x != yতুলনায় আরো অনেক কিছু পাঠযোগ্যnot x == y


29
অনুশীলনে, যে শ্রেণীর __eq__সাথে বেমানান রয়েছে সেগুলি __ne__ফ্ল্যাট-আউট ভাঙা।
কেভিন

8
দয়া করে মনে রাখবেন যে এটির ক্ষেত্রে আরও একটি নির্দেশ থাকে তা সত্য নয় not x == y। আমি যখন কোডটি ifএকটিতে রেখেছি , তখন দেখা গেল যে তাদের উভয়েরই একই সংখ্যক নির্দেশনা রয়েছে, কেবল একটি ছিল POP_JUMP_IF_TRUEএবং অপরটি POP_JUMP_IF_FALSE(এটি কেবলমাত্র ভিন্ন ব্যবহার ব্যতীত তাদের মধ্যে পার্থক্য ছিল COMPARE_OP)। আমি ifএস ছাড়াই কোডটি কম্পাইল করেছিলাম , আপনি যা পেয়েছেন তা পেয়েছি।
জাস্টিন

1
যেখানে ==এবং !=পারস্পরিক একচেটিয়া নয় অন্য উদাহরণ হ'ল একটি এসকিউএল-এর মতো বাস্তবায়ন যা nullমানগুলিকে অন্তর্ভুক্ত করে। SQL এর যে nullফেরত দেয় না trueকরার !=অন্য কোন মান তুলনায় সুতরাং এসকিউএল ইন্টারফেস পাইথন বাস্তবায়নের এছাড়াও একই সমস্যা থাকতে পারে।
জো

আমি ইচ্ছে করতে শুরু করছি যে আমি এর মধ্যে সম্ভাব্য পার্থক্যটি উল্লেখ না করলাম not ==এবং !=এটি আমার উত্তরের সবচেয়ে আকর্ষণীয় অংশ বলে মনে হচ্ছে! আমি মনে করি না যে এটি কেন থাকার জায়গা এটি যদি, কেন এবং কখন তা বোধগম্য হয় - দেখুন উদাহরণস্বরূপ পাইথনের কেন __ne__কেবল ন্যায়বিচারের পরিবর্তে অপারেটর পদ্ধতি রয়েছে __eq__?
jonrsharpe

29

@ জোনারশপেতে যা চলছে তার দুর্দান্ত ব্যাখ্যা রয়েছে। আমি ভেবেছিলাম যে 3 টি বিকল্পের 10,000,000,000 বার চালানোর সময় আমি কেবল সময়ের মধ্যে পার্থক্যটি দেখাব (সামান্য পার্থক্য প্রদর্শনের জন্য যথেষ্ট)।

কোড ব্যবহৃত:

def a(x):
    if x != 'val':
        pass


def b(x):
    if not x == 'val':
        pass


def c(x):
    if x == 'val':
        pass
    else:
        pass


x = 1
for i in range(10000000):
    a(x)
    b(x)
    c(x)

এবং সিপ্রোফাইল প্রোফাইলার ফলাফল:

এখানে চিত্র বর্ণনা লিখুন

সুতরাং আমরা দেখতে পাচ্ছি তার মাঝে ~ 0.7% খুব মিনিট পার্থক্য হল যে if not x == 'val':if x != 'val':। এর if x != 'val':মধ্যে দ্রুততম।

তবে সবচেয়ে আশ্চর্যের বিষয়, আমরা এটি দেখতে পারি

if x == 'val':
        pass
    else:

প্রকৃতপক্ষে দ্রুততম, এবং if x != 'val':~ 0.3% দ্বারা প্রহার করে। এটি খুব পঠনযোগ্য নয়, তবে আমার ধারণা আপনি যদি কর্মক্ষেত্রের একটি নগণ্য উন্নতি চান তবে কেউ এই পথে নামতে পারে।


31
আমি আশা করি সবাই জানেন যে এই তথ্যটিতে কাজ না করা ! 0.3% উন্নতির জন্য অপঠনযোগ্য পরিবর্তনগুলি করা - বা এমনকি 10% উন্নতি - খুব কমই খুব ভাল ধারণা এবং এই ধরণের উন্নতি খুব সম্ভবত বিস্মৃত হওয়ার সম্ভাবনা রয়েছে (এবং ভাল উপায়ে নয় : পাইথন রানটাইমের খুব সামান্য পরিবর্তন) কোনও লাভকে বিলোপ করতে বা বিপরীত করতে পারে
মালভোলিও

1
@ মালভোলিও ছাড়াও পাইথনের বিভিন্ন প্রয়োগ রয়েছে।
সিইস টিমারম্যান

6

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


5
>>> from dis import dis
>>> dis(compile('not 10 == 20', '', 'exec'))
  1           0 LOAD_CONST               0 (10)
              3 LOAD_CONST               1 (20)
              6 COMPARE_OP               2 (==)
              9 UNARY_NOT
             10 POP_TOP
             11 LOAD_CONST               2 (None)
             14 RETURN_VALUE
>>> dis(compile('10 != 20', '', 'exec'))
  1           0 LOAD_CONST               0 (10)
              3 LOAD_CONST               1 (20)
              6 COMPARE_OP               3 (!=)
              9 POP_TOP
             10 LOAD_CONST               2 (None)
             13 RETURN_VALUE

এখানে আপনি দেখতে পারেন যে not x == yএর চেয়ে আরও একটি নির্দেশ রয়েছে x != y। সুতরাং বেশিরভাগ ক্ষেত্রে পারফরম্যান্সের পার্থক্য খুব কম হবে যদি না আপনি লক্ষ লক্ষ তুলনা করছেন এবং তারপরেও এটি সম্ভবত কোনও বাধা হয়ে দাঁড়াবে না।


5

একটি অতিরিক্ত নোট, যেহেতু অন্যান্য উত্তরগুলি আপনার প্রশ্নের উত্তর বেশিরভাগই সঠিকভাবে দিয়েছে, তা হ'ল যদি কোনও শ্রেণি কেবলমাত্র সংজ্ঞায়িত করে __eq__()এবং না __ne__(), তবে আপনার COMPARE_OP (!=)চালানো __eq__()এবং এটিকে উপেক্ষা করবেন । সেই সময়ে, আপনার তৃতীয় বিকল্পটি সম্ভবত সামান্য কিছুটা দক্ষ হওয়ার সম্ভাবনা রয়েছে, তবে দ্রুত বিবেচনা করা কঠিন বলে আপনার গতির প্রয়োজন হয় কেবল তখনই বিবেচনা করা উচিত।


3

এটি আপনার পড়ার পদ্ধতি সম্পর্কে। notঅপারেটর গতিশীল, এজন্য আপনি এটি প্রয়োগ করতে সক্ষম হন

if not x == 'val':

তবে !=অপারেটর হিসাবে আরও ভাল প্রসঙ্গে পড়া যেতে পারে যা বিপরীতে কাজ ==করে।


3
" notঅপারেটর গতিশীল" বলতে কী বোঝ ?
jonrsharpe

1
@jonrsharpe মনে হয় তিনি অর্থ হল, "না X" ডাকব এক্স .__ bool, __ () [পাইথন 3 - পাইথন 2 ব্যবহারসমূহ অশূন্য ] এবং ফলাফলের প্রত্যাবর্তন (দেখুন docs.python.org/3/reference/datamodel.html#object। __বুল__ )
jdferreira

1

আমি উপরে আমার পাঠযোগ্যতার মন্তব্যটি প্রসারিত করতে চাই।

আবার, আমি অন্যান্য (পারফরম্যান্স-তুচ্ছ) উদ্বেগকে ওভাররাইডে পঠনযোগ্যতার সাথে সম্পূর্ণ একমত।

আমি যে বিষয়টি উল্লেখ করতে চাই তা হ'ল মস্তিষ্ক "পজিটিভ" দ্রুত "নেতিবাচক" এর চেয়ে দ্রুত ব্যাখ্যা করে। উদাহরণস্বরূপ, "থামুন" বনাম। "যাবেন না" (শব্দের সংখ্যার পার্থক্যের কারণে একটি উল্টো উদাহরণ)।

সুতরাং একটি পছন্দ দেওয়া হয়েছে:

if a == b
    (do this)
else
    (do that)

কার্যকারিতা সমতুল্য:

if a != b
    (do that)
else
    (do this)

কম পাঠযোগ্যতা / বোধগম্যতা আরও বেশি বাগের দিকে নিয়ে যায়। সম্ভবত প্রাথমিক কোডিংয়ে নয়, তবে (আপনার মতো স্মার্ট নয়) রক্ষণাবেক্ষণ পরিবর্তন হয় ...


1
মস্তিষ্ক "পজেটিভ" এর তুলনায় দ্রুত ব্যাখ্যা করে যা "নেতিবাচক" এর চেয়ে বেশি এটি অভিজ্ঞতা থেকে বা আপনি এই বিষয়ে পড়াশোনাটি পড়েছেন? আমি কেবল জিজ্ঞাসা করছি কারণ কোডটি (এটি করুন) বা (এটি করুন) এর উপর নির্ভর করে আমি বুঝতে পারি!
লাফার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.