এই দুটি লাইনের কোডের মধ্যে পার্থক্য কী:
if not x == 'val':
এবং
if x != 'val':
একজনের কি অন্যের চেয়ে বেশি দক্ষ?
এটি ব্যবহার করা ভাল
if x == 'val':
pass
else:
এই দুটি লাইনের কোডের মধ্যে পার্থক্য কী:
if not x == 'val':
এবং
if x != 'val':
একজনের কি অন্যের চেয়ে বেশি দক্ষ?
এটি ব্যবহার করা ভাল
if x == 'val':
pass
else:
উত্তর:
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
।
__eq__
সাথে বেমানান রয়েছে সেগুলি __ne__
ফ্ল্যাট-আউট ভাঙা।
not x == y
। আমি যখন কোডটি if
একটিতে রেখেছি , তখন দেখা গেল যে তাদের উভয়েরই একই সংখ্যক নির্দেশনা রয়েছে, কেবল একটি ছিল POP_JUMP_IF_TRUE
এবং অপরটি POP_JUMP_IF_FALSE
(এটি কেবলমাত্র ভিন্ন ব্যবহার ব্যতীত তাদের মধ্যে পার্থক্য ছিল COMPARE_OP
)। আমি if
এস ছাড়াই কোডটি কম্পাইল করেছিলাম , আপনি যা পেয়েছেন তা পেয়েছি।
==
এবং !=
পারস্পরিক একচেটিয়া নয় অন্য উদাহরণ হ'ল একটি এসকিউএল-এর মতো বাস্তবায়ন যা null
মানগুলিকে অন্তর্ভুক্ত করে। SQL এর যে null
ফেরত দেয় না true
করার !=
অন্য কোন মান তুলনায় সুতরাং এসকিউএল ইন্টারফেস পাইথন বাস্তবায়নের এছাড়াও একই সমস্যা থাকতে পারে।
not ==
এবং !=
এটি আমার উত্তরের সবচেয়ে আকর্ষণীয় অংশ বলে মনে হচ্ছে! আমি মনে করি না যে এটি কেন থাকার জায়গা এটি যদি, কেন এবং কখন তা বোধগম্য হয় - দেখুন উদাহরণস্বরূপ পাইথনের কেন __ne__
কেবল ন্যায়বিচারের পরিবর্তে অপারেটর পদ্ধতি রয়েছে __eq__
?
@ জোনারশপেতে যা চলছে তার দুর্দান্ত ব্যাখ্যা রয়েছে। আমি ভেবেছিলাম যে 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% দ্বারা প্রহার করে। এটি খুব পঠনযোগ্য নয়, তবে আমার ধারণা আপনি যদি কর্মক্ষেত্রের একটি নগণ্য উন্নতি চান তবে কেউ এই পথে নামতে পারে।
প্রথমটিতে পাইথনকে প্রয়োজনের তুলনায় আরও একটি ক্রিয়াকলাপ চালাতে হয় (কেবল সমান নয় এটি যাচাইয়ের পরিবর্তে এটি সমান কিনা তা সত্য নয় কিনা তা পরীক্ষা করে দেখতে হবে, সুতরাং আরও একটি অপারেশন)। একটি মৃত্যুদন্ড কার্যকর হওয়া থেকে পার্থক্যটি বলা অসম্ভব, তবে যদি বহুবার চালানো হয় তবে দ্বিতীয়টি আরও কার্যকর হবে। সামগ্রিকভাবে আমি দ্বিতীয়টি ব্যবহার করব, তবে গাণিতিকভাবে সেগুলি একই
>>> 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
। সুতরাং বেশিরভাগ ক্ষেত্রে পারফরম্যান্সের পার্থক্য খুব কম হবে যদি না আপনি লক্ষ লক্ষ তুলনা করছেন এবং তারপরেও এটি সম্ভবত কোনও বাধা হয়ে দাঁড়াবে না।
একটি অতিরিক্ত নোট, যেহেতু অন্যান্য উত্তরগুলি আপনার প্রশ্নের উত্তর বেশিরভাগই সঠিকভাবে দিয়েছে, তা হ'ল যদি কোনও শ্রেণি কেবলমাত্র সংজ্ঞায়িত করে __eq__()
এবং না __ne__()
, তবে আপনার COMPARE_OP (!=)
চালানো __eq__()
এবং এটিকে উপেক্ষা করবেন । সেই সময়ে, আপনার তৃতীয় বিকল্পটি সম্ভবত সামান্য কিছুটা দক্ষ হওয়ার সম্ভাবনা রয়েছে, তবে দ্রুত বিবেচনা করা কঠিন বলে আপনার গতির প্রয়োজন হয় কেবল তখনই বিবেচনা করা উচিত।
এটি আপনার পড়ার পদ্ধতি সম্পর্কে। not
অপারেটর গতিশীল, এজন্য আপনি এটি প্রয়োগ করতে সক্ষম হন
if not x == 'val':
তবে !=
অপারেটর হিসাবে আরও ভাল প্রসঙ্গে পড়া যেতে পারে যা বিপরীতে কাজ ==
করে।
not
অপারেটর গতিশীল" বলতে কী বোঝ ?
আমি উপরে আমার পাঠযোগ্যতার মন্তব্যটি প্রসারিত করতে চাই।
আবার, আমি অন্যান্য (পারফরম্যান্স-তুচ্ছ) উদ্বেগকে ওভাররাইডে পঠনযোগ্যতার সাথে সম্পূর্ণ একমত।
আমি যে বিষয়টি উল্লেখ করতে চাই তা হ'ল মস্তিষ্ক "পজিটিভ" দ্রুত "নেতিবাচক" এর চেয়ে দ্রুত ব্যাখ্যা করে। উদাহরণস্বরূপ, "থামুন" বনাম। "যাবেন না" (শব্দের সংখ্যার পার্থক্যের কারণে একটি উল্টো উদাহরণ)।
সুতরাং একটি পছন্দ দেওয়া হয়েছে:
if a == b
(do this)
else
(do that)
কার্যকারিতা সমতুল্য:
if a != b
(do that)
else
(do this)
কম পাঠযোগ্যতা / বোধগম্যতা আরও বেশি বাগের দিকে নিয়ে যায়। সম্ভবত প্রাথমিক কোডিংয়ে নয়, তবে (আপনার মতো স্মার্ট নয়) রক্ষণাবেক্ষণ পরিবর্তন হয় ...