Does tuple() copy the elements of the argument?
Question: In python, does the built-in function `tuple([iterable])` create a tuple
object and fill it with copies of the elements of "iterable", or does it
create a tuple containing references to the already existing objects of
"iterable"?


Answer: `tuple` will iterate the sequence and copy the values. The underlying sequence
will be _not_ stored to actually keep the values, but the tuple representation
will replace it. So yes, the conversion to a tuple is actual work and not just
some nesting of another type.

You can see this happening when converting a generator:

    
    
    >>> def gen ():
            for i in range(5):
                print(i)
                yield i
    >>> g = gen()
    >>> g
    <generator object gen at 0x00000000030A9B88>
    >>> tuple(g)
    0
    1
    2
    3
    4
    (0, 1, 2, 3, 4)
    

As you can see, the generator is immediately iterated, making the values
generate. Afterwards, the tuple is self-contained, and no reference to the
original source is kept. For reference, `list()` behaves in exactly the same
way but creates a list instead.

The behaviour that 275365 pointed out (in the now deleted answer) is the
standard copying behaviour of Python values. Because everything in Python is
an object, you are essentially only working with references. So when
references are copied, the underlying object is not copied. The important bit
is that non-mutable objects will be recreated whenever their value changes
which will not update all previously existing references but just the one
reference you are currently changing. That’s why it works like this:

    
    
    >>> source = [[1], [2], [3]]
    >>> tpl = tuple(source)
    >>> tpl
    ([1], [2], [3])
    >>> tpl[0].append(4)
    >>> tpl
    ([1, 4], [2], [3])
    >>> source
    [[1, 4], [2], [3]]
    

`tpl` still contains a reference to the original objects within the `source`
list. As those are lists, they are mutable. Changing a mutable list anywhere
will not invalidate the references that exist to that list, so the change will
appear in both `source` and `tpl`. The actual source list however is only
stored in `source`, and `tpl` has no reference to it:

    
    
    >>> source.append(5)
    >>> source
    [[1, 4], [2], [3], 5]
    >>> tpl
    ([1, 4], [2], [3])
    

