পাইথনে "0, 0 == (0, 0)" সমান "(0, মিথ্যা)" কেন?


118

পাইথনে (আমি কেবল পাইথন ৩.6 দিয়ে পরীক্ষা করেছি তবে আমি বিশ্বাস করি এটি পূর্ববর্তী সংস্করণগুলিরও বেশিরভাগের জন্য রাখা উচিত):

(0, 0) == 0, 0   # results in a two element tuple: (False, 0)
0, 0 == (0, 0)   # results in a two element tuple: (0, False)
(0, 0) == (0, 0) # results in a boolean True

কিন্তু:

a = 0, 0
b = (0, 0)
a == b # results in a boolean True

ফলাফল দুটি পদ্ধতির মধ্যে পৃথক হয় কেন? সাম্যতা অপারেটর কি আলাদাভাবে টিপলগুলি পরিচালনা করে?

উত্তর:


156

প্রথম দুটি এক্সপ্রেশন উভয় টিপলস হিসাবে পার্স:

  1. (0, 0) == 0(যা হয় False), তারপরে অনুসরণ করা0
  2. 0, তারপরে 0 == (0, 0)(যা এখনও এখনও Falseসেই পথে রয়েছে)।

সাম্যতা অপারেটরের তুলনায় কমা বিভাজকের তুলনামূলক প্রাধান্যের কারণে এক্সপ্রেশনগুলি সেভাবে বিভক্ত হয়: পাইথন দুটি টিপলসের মধ্যে সমতা পরীক্ষার পরিবর্তে একটি সমতা পরীক্ষা বলে দুটি অভিব্যক্তি সমন্বিত একটি টুপল দেখায়।

তবে আপনার দ্বিতীয় সেট স্টেটমেন্টে, টিউপল হতে a = 0, 0 পারে না । একটি টিপল মানগুলির সংগ্রহ এবং সমতা পরীক্ষার বিপরীতে পাইথনে অ্যাসাইনমেন্টের কোনও মূল্য থাকে না। একটি অ্যাসাইনমেন্ট একটি অভিব্যক্তি নয়, একটি বিবৃতি; এটির কোনও মান নেই যা একটি টিপল বা অন্য কোনও আশেপাশের অভিব্যক্তিতে অন্তর্ভুক্ত করা যেতে পারে। আপনি (a = 0), 0টিউপল হিসাবে ব্যাখ্যা জোর করার জন্য এমন কিছু চেষ্টা করলে আপনি একটি বাক্য গঠন ত্রুটি পাবেন। এটি একটি ভেরিয়েবলের উপর একটি টুপলের অ্যাসাইনমেন্ট ছেড়ে দেয় - যা কেবল এটির দ্বারা a = (0, 0)বৈধ ব্যাখ্যা হিসাবে এটি লিখে আরও স্পষ্ট করা যায় a = 0, 0

এমনকি অ্যাসাইনমেন্টের প্রথম বন্ধনী ছাড়াই এটি aউভয়ই এবং bমূল্য নির্ধারণ করা হয় (0,0), সুতরাং a == bতাই True


17
আমি বলতে চাই যে কমা অপারেটরের সাম্যতার চেয়ে কম অগ্রাধিকার রয়েছে, যেহেতু সমতা মূল্যায়ন কমা অপারেটরের চেয়ে আগে: সমতাটি কমা অপারেটরের চেয়ে উচ্চতর প্রাধান্য পায়। তবে এটি সর্বদা বিভ্রান্তির উত্স; কেবলমাত্র এটিই নির্দেশ করতে চেয়েছিলেন যে অন্যান্য উত্সগুলি প্রায় জিনিসগুলি ফ্লিপ করতে পারে।
টমসডিং

2
আপনি কম / উচ্চতর ভার্চিয়াজ বিভ্রান্তি এড়াতে পারেন যে পরিবর্তে ,কম শক্ত করে বাঁধেন ==
অমলয়

4
কমা হয় না একটি অপারেটর docs.python.org/3.4/faq/...
Chris_Rands

48
ডক্স দাবী করতে পারে যে তারা যা চায়, কিন্তু তাতে কিছু আসে যায় না। আপনি কোনও পার্সার লিখতে পারেন যাতে প্রতিটি অপারেটর তার নিজস্ব উত্পাদন পায় এবং বাস্তবায়নের কোথাও কোনও স্পষ্ট "নজির" নেই, তবে এটি সেই সিনট্যাকটিক ইউনিটগুলিকে অপারেটর হওয়া থেকে বিরত রাখে না You আপনি কিছু "বাস্তবায়ন-নির্দিষ্ট পদ্ধতিতে" অপারেটরকে নতুন করে সংজ্ঞায়িত করতে পারেন , যা স্পষ্টতই পাইথনে তারা করেছিল, কিন্তু এটি এই শব্দটির অর্থকে পরিবর্তন করে না। কমা কার্যকরভাবে একটি অপারেটর যা টিপলস উত্পাদন করে। এটির অপারেটরনেস উদাহরণস্বরূপ, বন্ধুত্ব দ্বারা যেভাবে এর আপেক্ষিক অগ্রাধিকার প্রভাবিত হয় তাতে প্রদর্শিত হয়।
মার্ক রিড

68

আপনি সমস্ত 3 টি দৃষ্টিতে যা দেখেন তা হ'ল ভাষার ব্যাকরণের নির্দিষ্টকরণের ফলাফল এবং উত্স কোডে টোকেনগুলি কীভাবে পার্স ট্রি তৈরি করতে পার্স হয়।

এই নিম্ন স্তরের কোডটি একবার দেখার জন্য হুডের নীচে কী ঘটে তা বুঝতে আপনাকে সহায়তা করা উচিত। আমরা এই পাইথন স্টেটমেন্টগুলি নিতে পারি, এগুলিকে বাইট কোডে রূপান্তর করতে পারি এবং তারপরে disমডিউলটি ব্যবহার করে সেগুলি ছড়িয়ে দিতে পারি :

মামলা 1: (0, 0) == 0, 0

>>> dis.dis(compile("(0, 0) == 0, 0", '', 'exec'))
  1           0 LOAD_CONST               2 ((0, 0))
              3 LOAD_CONST               0 (0)
              6 COMPARE_OP               2 (==)
              9 LOAD_CONST               0 (0)
             12 BUILD_TUPLE              2
             15 POP_TOP
             16 LOAD_CONST               1 (None)
             19 RETURN_VALUE

(0, 0)প্রথম সাথে প্রথম তুলনা করা হয় 0এবং এর সাথে মূল্যায়ন করা হয় False। এরপরে একটি টিপল তৈরি করা হয় এই ফলাফলটি দিয়ে এবং শেষটি 0, যাতে আপনি পান (False, 0)

কেস 2: 0, 0 == (0, 0)

>>> dis.dis(compile("0, 0 == (0, 0)", '', 'exec'))
  1           0 LOAD_CONST               0 (0)
              3 LOAD_CONST               0 (0)
              6 LOAD_CONST               2 ((0, 0))
              9 COMPARE_OP               2 (==)
             12 BUILD_TUPLE              2
             15 POP_TOP
             16 LOAD_CONST               1 (None)
             19 RETURN_VALUE

0প্রথম উপাদান হিসাবে একটি tuple নির্মিত হয় । দ্বিতীয় উপাদানটির জন্য, প্রথম ক্ষেত্রে হিসাবে একই চেক করা হয় এবং মূল্যায়ন করা হয় False, যাতে আপনি পান (0, False)

কেস 3: (0, 0) == (0, 0)

>>> dis.dis(compile("(0, 0) == (0, 0)", '', 'exec'))
  1           0 LOAD_CONST               2 ((0, 0))
              3 LOAD_CONST               3 ((0, 0))
              6 COMPARE_OP               2 (==)
              9 POP_TOP
             10 LOAD_CONST               1 (None)
             13 RETURN_VALUE

এখানে, যেমন আপনি দেখতে পাচ্ছেন, আপনি কেবল এই দুটি (0, 0)টিপল তুলনা করে ফিরে যাচ্ছেন True


20

সমস্যাটি বোঝানোর আরেকটি উপায়: আপনি সম্ভবত অভিধানের অক্ষরগুলির সাথে পরিচিত

{ "a": 1, "b": 2, "c": 3 }

এবং অ্যারে আক্ষরিক

[ "a", "b", "c" ]

এবং tuple আক্ষরিক

( 1, 2, 3 )

তবে আপনি যা বুঝতে পারছেন না সেটি হল অভিধান এবং অ্যারে লিটারালগুলির বিপরীতে, আপনি সাধারণত একটি টিউপল লিটারেলের চারপাশে যে প্রথম বন্ধনী দেখেন তা আক্ষরিক বাক্য গঠনের অংশ নয় । টিপলসগুলির জন্য আক্ষরিক সিনট্যাক্স হ'ল কমা দ্বারা পৃথক করা এক্সপ্রেশনগুলির ক্রম:

1, 2, 3

( পাইথনের আনুষ্ঠানিক ব্যাকরণের ভাষায় একটি "এক্সপ্রিলিস্ট" )।

এখন, আপনি অ্যারে আক্ষরিক কী আশা করেন?

[ 0, 0 == (0, 0) ]

মূল্যায়ন করতে? এটি সম্ভবত আরো অনেক বলে মনে হচ্ছে উচিত অনুরূপ হতে

[ 0, (0 == (0, 0)) ]

যা অবশ্যই মূল্যায়ন করে [0, False]। একইভাবে, একটি স্পষ্টতই প্রথম বন্ধনীযুক্ত টুপল আক্ষরিক সাথে

( 0, 0 == (0, 0) )

এটা পেয়ে অবাক হওয়ার কিছু নেই (0, False)। তবে প্রথম বন্ধনীগুলি alচ্ছিক;

0, 0 == (0, 0)

একই জিনিস। এবং সে কারণেই আপনি পান (0, False)


আপনি যদি ভাবছেন যে টিউপল আক্ষরিক চারপাশের প্রথম বন্ধনীগুলি alচ্ছিক কেন , তবে এটি বেশিরভাগ ক্ষেত্রে কারণ ধ্বংসাত্মক অ্যাসাইনমেন্টগুলি লিখতে হবে তাই বিরক্তিকর হবে:

(a, b) = (c, d) # meh
a, b = c, d     # better

17

ক্রমগুলি সম্পাদিত হয় এমন ক্রমের চারপাশে বেশ কয়েকটি বন্ধনী যুক্ত করা আপনাকে ফলাফলগুলি আরও ভালভাবে বুঝতে সহায়তা করতে পারে:

# Build two element tuple comprising of 
# (0, 0) == 0 result and 0
>>> ((0, 0) == 0), 0
(False, 0)

# Build two element tuple comprising of
# 0 and result of (0, 0) == 0 
>>> 0, (0 == (0, 0))
(0, False)

# Create two tuples with elements (0, 0) 
# and compare them
>>> (0, 0) == (0, 0) 
True

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

(0, 0) == 0 ,   0
#-----------|------
  expr 1      expr2

টিপলটিও (0, 0)একইভাবে ভেঙে যেতে পারে। কমা আক্ষরিক সমন্বয়ে দুটি অভিব্যক্তি আলাদা করে 0


6

প্রথমটিতে পাইথন দুটি জিনিস নিয়ে কাজ করছে:

  1. অভিব্যক্তি (0, 0) == 0, যা মূল্যায়ন করেFalse
  2. ধ্রুবক 0

দ্বিতীয়টির মধ্যে এটি অন্যভাবে।


0

এই উদাহরণটি দেখুন:

r = [1,0,1,0,1,1,0,0,0,1]
print(r==0,0,r,1,0)
print(r==r,0,1,0,1,0)

তারপরে ফলাফল:

False 0 [1, 0, 1, 0, 1, 1, 0, 0, 0, 1] 1 0
True 0 1 0 1 0

তারপরে তুলনা উদাহরণে প্রথম সংখ্যা (0 এবং r) এর সাথে কেবল করে।

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