Ok let me explain you in detail :
When you do l.append(l) , then l points to [1,2,3,[…]] indicating that l contains itself right ?
Now when you do l=l+[2,3,4,4] , so the following operation takes place :
l = [1,2,3,[...]] + [2,3,4,4]
print(l)
So when you print this the output comes out to be [1,2,3,[1,2,3,[…]],2,3,4,4] right ?
So here you would observe that the […] has been replaced by the whole l which points to [1,2,3,[…]].
Have you ever tried printing […] ? If you would print l[3][3] , then you would see that […] is nothing but the whole list [1,2,3,[…]].
Now coming to the other question you asked :
new_l = l[3] means new_l is also [1,2,3,[…]]. Here also […] means the whole combined list. So if you print new_l[3] it would again give you [1,2,3,[…]]. This would happen recursively. You can try printing new_l[3][3][3][3]…you would always get [1,2,3,[…]].
I would suggest you should try printing things to get a more clear picture of what is […]_
[…] is basically the whole combined list i.e. [1,2,3,[…]]
Hope this helps.
Happy Learning