خب سوال چالش قبلی بهانه ای بود برای اینکه کمی راجع به لیست هایی که خودشون یکی از اعضای خودشون هستن یا اصطلاحا self-referenced lists ها صحبت کنیم.
lst = [1, 2, 3]
lst[0] = lst
دقت کنید ما وقتی عضو اول لیست رو تغییر دادیم، حاصل نمیشه این :
[[1, 2, 3], 2, 3]
چرا ؟ چون وقتی که داریم اون لیست داخلیه رو مینویسیم ، عضو اول خودش باز باید بشه خودش ! یعنی یه حالت تو در تو ی بینهایت به این شکل :
[[[[[[1, 2, 3], 2, 3], 2, 3], 2, 3], 2, 3], 2, 3]
ما تا همینجا کفایت کردیم ولی باز هم جای اون 1 باید این روند ادامه پیدا میکرد. پس پایتون نمیتونه همچین لیستی رو برای ما نمایش بده. به جاش از "..." استفاده میکنه.

قبل از اینکه بریم سراغ جواب این نکته رو هم یا آوری کنیم که self referenced list ها هیچوقت تعداد رفرنسی که بهشون هست صفر نمیشه حتی اگر بزنید del lst. پس در نتیجه توسط مکانیزم reference counting پایتون از بین نمیرن و ممکنه تا آخر برنامه ram رو اشغال کنن (مگر در شرایطی که garbage collector وارد عمل بشه)

اما جواب :
پس گفتیم پایتون به محض اینکه متوجه بشه داره بصورت بینهایت print انجام میده جای اون 3 تا نقطه میذاره.
"ولی کی متوجه میشه" جواب این سواله.

وقتی ما لیست رو با متد .sort مرتب میکنیم ، چون عمل in-place هست ، لیست جدید ساخته نمیشه و ID اون لیست تغییر نمیکنه ! انگار که :
x = [x, x, x]
پس پایتون فورا متوجه این recursion میشه و اون ها رو با "..." جایگزین میکنه.

ولی وقتی لیستمون رو با فانکشن sorted() مرتب میکنیم خروجی یه لیست جدید هست انگار که بگیم :
y = [x, x, x]
پس موقع print کردن آیتم های داخل لیست، پایتون "در مرحله ی اول" متوجه این recursion نمیشه ! چرا ؟ چون y یه لیست جدید هست پس با x فرق داره. پس یه لیستی داریم که شامل 3 تا لیست دیگس همین. ولی از مرحله ی دوم که داره خود x ها رو نگاه میکنه (یا بهتره بگیم لایه ی داخلی تر) برای print کردن متوجه این recursion میشه ! پس این میشه که 2 تا لیستی باهم برابر هستن موقع print کردن ، representation های متفاوتی دارن.
print(lst == sorted(lst)) # True
print(str(lst) == str(sorted(lst)))
# False

1 comment