چالش روزانه · ۲۲ مهر ۱۴۰۵
چالش پایتون ۱: += روی لیست؛ تغییر یا ساختن؟
قبل از اجرای کد، خروجی آن را پیشبینی کن. حدس نزن؛ خط به خط فکر کن پایتون چه میکند.
a = [1, 2, 3]
b = a
b += [4]
b = b + [5]
print(a, b)نمایش پاسخ و توضیح
پاسخ درست: گزینهٔ ب — [1, 2, 3, 4] [1, 2, 3, 4, 5]
خط به خط
a = [1, 2, 3]یک لیست میسازد و نامaرا به آن میچسباند.b = aلیست جدید نمیسازد؛ فقط نام دومbرا به همان لیست میچسباند. حالا یک شیء داریم با دو اسم.b += [4]برای لیستها درجا (in-place) کار میکند: پایتون متد__iadd__را صدا میزند که عملاً همانextendاست. پس خود لیست مشترک عوض میشود وaهم[1, 2, 3, 4]را میبیند.b = b + [5]فرق دارد: عملگر+همیشه یک لیست جدید میسازد و بعدbبه آن لیست تازه چسبانده میشود. از این لحظهaوbدیگر یک شیء نیستند.
پس a میماند [1, 2, 3, 4] و b میشود [1, 2, 3, 4, 5].
با id ببینید
تابع id() شناسهٔ هر شیء را برمیگرداند. اگر دو نام id یکسان داشته باشند، یعنی به یک شیء اشاره میکنند:
a = [1, 2, 3]
b = a
print(a is b) # True
b += [4]
print(a is b) # هنوز True — همان لیست تغییر کرد
b = b + [5]
print(a is b) # False — b حالا لیست جدیدی است
نکتهٔ امتحانی
- برای انواع تغییرپذیر (list، dict، set)،
x += yمعمولاً درجاست؛ ولیx = x + yشیء جدید میسازد. - برای انواع تغییرناپذیر (int، str، tuple) هر دو شکل شیء جدید میسازند، چون اصلاً نمیشود خودشان را تغییر داد.
- اگر واقعاً کپی مستقل میخواهید:
b = a.copy()یاb = a[:].
حالا خودت اجرا کن و تغییرش بده
a = [1, 2, 3]
b = a
b += [4]
b = b + [5]
print(a, b)