Is the variable new a reference to the original object 'df' (i.e.
mutable and exposed) or it is now referred to a new instance?
Why don't you just...
In [516]: id(df)
Out[516]: 4481803432
In [517]: id(t[1])
Out[517]: 4481803432
I thought tuple (similar to the behavior string) that it always gives
you a new object unlike list...
Wrong. The only difference between tuple
s and list
s is that the former is immutable. Both would become a container for the same references.
So I thought if we call a DataFrame in a tuple will create a new
object without having the need to do the .copy()
It does not. You will need to explicitly call .copy()
if you want a copy. Otherwise you're working with the same reference.
Can I safely say that it is always a good practice to do a copy() to
avoid mutation?
Not really, because most of the dataframe mutation methods return a copy of the dataframe. Changes are never made inplace unless you explicitly request it (such as using the inplace=True
flag).
You should know that setting inplace=True
does not improve performance because a copy is internally created and then assigned back to the original.