পাইথনে a - = b এবং a = a - b এর মধ্যে পার্থক্য


90

আমি সম্প্রতি ম্যাট্রিক্সের প্রতিটি এন সারির গড়ের জন্য এই সমাধানটি প্রয়োগ করেছি । যদিও সমাধানটি সাধারণভাবে কাজ করে তবে 7x1 অ্যারে প্রয়োগ করার সময় আমার সমস্যা হয়েছিল। আমি লক্ষ্য করেছি যে সমস্যাটি -=অপারেটর ব্যবহার করার সময় । একটি ছোট উদাহরণ তৈরি করতে:

import numpy as np

a = np.array([1,2,3])
b = np.copy(a)

a[1:] -= a[:-1]
b[1:] = b[1:] - b[:-1]

print a
print b

কোন ফলাফল:

[1 1 2]
[1 1 1]

সুতরাং, অ্যারের ক্ষেত্রে a -= bএকটি ভিন্ন ফলাফল উত্পাদন করে a = a - b। আমি এখন অবধি ভাবলাম যে এই দুটি উপায় হুবহু এক are পার্থক্য কি?

আমি ম্যাট্রিক্সে প্রতিটি এন সারি সংশ্লেষের জন্য যে পদ্ধতিটি উল্লেখ করছি সেটি কীভাবে কাজ করবে যেমন 7x4 ম্যাট্রিক্সের জন্য তবে 7x1 অ্যারের জন্য নয়?

উত্তর:


80

দ্রষ্টব্য: NumPy অ্যারেগুলিতে ইন-প্লেস ক্রিয়াকলাপগুলি ব্যবহার করে যা মেমরি ভাগ করে না ভার্সন 1.13.0 এর পরে (বিবরণ এখানে দেখুন )। দুটি অপারেশন একই ফলাফল উত্পাদন করবে। এই উত্তরটি কেবলমাত্র NumPy এর পূর্ববর্তী সংস্করণগুলিতে প্রযোজ্য।


গণনা ব্যবহারের সময় অ্যারেগুলিকে মিউটেশন করা অপ্রত্যাশিত ফলাফলের দিকে নিয়ে যেতে পারে!

প্রশ্নের উদাহরণে, বিয়োগের -=দ্বিতীয় উপাদানটিকে সংশোধন করে aএবং তত্ক্ষণাত তৃতীয় উপাদানের ক্রিয়ায় সেই সংশোধিত দ্বিতীয় উপাদানটি ব্যবহার করে a

a[1:] -= a[:-1]ধাপে ধাপে যা ঘটে তা এখানে :

  • aডেটা সহ অ্যারে হয় [1, 2, 3]

  • এই ডেটাতে আমাদের দুটি মতামত রয়েছে: a[1:]হয় [2, 3]এবং a[:-1]হয় [1, 2]

  • ইন-প্লেস বিয়োগ -=শুরু হয়। এর প্রথম উপাদানটি a[:-1]1 এর প্রথম উপাদানটি বিয়োগ করা হয় a[1:]। এটি aহতে সংশোধন করা হয়েছে [1, 1, 3]। এখন আমরা যে আছে a[1:]তথ্য একটি দৃশ্য [1, 3]a[:-1]ডেটার একটি দৃশ্য [1, 1](অ্যারে দ্বিতীয় উপাদান aপরিবর্তন করা হয়েছে)।

  • a[:-1]এখন [1, 1]এবং NumPy এখন তার দ্বিতীয় উপাদান বিয়োগ আবশ্যক যা 1 দ্বিতীয় উপাদান থেকে (আর 2!) a[1:]। এটি a[1:]মানগুলির একটি দৃষ্টিভঙ্গি তৈরি করে [1, 2]

  • aমানগুলির সাথে এখন একটি অ্যারে [1, 1, 2]

b[1:] = b[1:] - b[:-1]এই সমস্যাটি নেই কারণ প্রথমে b[1:] - b[:-1]একটি নতুন অ্যারে তৈরি করে এবং তারপরে এই অ্যারেটিতে মানগুলি নির্ধারিত করে b[1:]bবিয়োগের সময় এটি নিজেকে পরিবর্তন করে না , সুতরাং দর্শনগুলি b[1:]এবং b[:-1]পরিবর্তন হয় না।


সাধারণ পরামর্শটি হ'ল যদি ওভারল্যাপ হয়ে যায় তবে একটি ভিউ অন্য স্থানে পরিবর্তন করে এড়ানো। এই অপারেটার অন্তর্ভুক্ত -=, *=ইত্যাদি এবং ব্যবহার out(যেমন সার্বজনীন ফাংশন প্যারামিটার np.subtractএবং np.multiply) অ্যারে এক ফিরে লিখতে।


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

43

অভ্যন্তরীণভাবে, পার্থক্যটি এটি:

a[1:] -= a[:-1]

এর সমতুল্য:

a[1:] = a[1:].__isub__(a[:-1])
a.__setitem__(slice(1, None, None), a.__getitem__(slice(1, None, None)).__isub__(a.__getitem__(slice(1, None, None)))

এই যখন:

b[1:] = b[1:] - b[:-1]

এটিতে মানচিত্র:

b[1:] = b[1:].__sub__(b[:-1])
b.__setitem__(slice(1, None, None), b.__getitem__(slice(1, None, None)).__sub__(b.__getitem__(slice(1, None, None)))

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

ন্যালি বস্তুগুলিতে স্লাইস ক্রিয়াকলাপ প্রয়োগ করা তাদের উপর দৃষ্টিভঙ্গি তৈরি করে, তাই এগুলি ব্যবহার করে সরাসরি "আসল" বস্তুর স্মৃতিতে প্রবেশ করে।


11

দস্তাবেজগুলি বলেছেন:

পাইথনে বর্ধিত অ্যাসাইনমেন্টের পেছনের ধারণাটি হ'ল বাম-হাতের অপারেণ্ডে বাইনারি অপারেশনের ফলাফল সংরক্ষণের সাধারণ অনুশীলনটি লেখার পক্ষে সহজ উপায় নয়, তবে বাম-হাতের অপারেণ্ডের জন্যও প্রশ্ন রয়েছে আপনার নিজের পরিবর্তিত অনুলিপি তৈরির পরিবর্তে এটি 'নিজেই' পরিচালনা করা উচিত তা জেনে রাখুন।

একটি থাম্ব নিয়ম অনুযায়ী, বৃদ্ধি বিয়োগ ( x-=y) হল x.__isub__(y)জন্য, ইন -place অপারেশন যদি সম্ভব, যখন স্বাভাবিক বিয়োগ ( x = x-y) হল x=x.__sub__(y)। পূর্ণসংখ্যার মতো অপরিবর্তনীয় বস্তুগুলিতে এটি সমতুল্য। তবে আপনার উদাহরণ হিসাবে যেমন অ্যারে বা তালিকার মতো পরিবর্তনীয় বিষয়গুলির জন্য তারা খুব আলাদা জিনিস হতে পারে।

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