It depends on the type of the given object you refer to as "array". If you meant the built-in type list
-- yes, a copy is made:
>>> a = ['X', 'Y', 'Z']
>>> a
['X', 'Y', 'Z']
>>> b = a[0:2]
>>> b
['X', 'Y']
>>> a[0] = 42 # we modify `a`
>>> a
[42, 'Y', 'Z']
>>> b # `b` did not change
['X', 'Y']
The same applies to many other sequence types; for example, to bytearray
:
>>> ar = bytearray(b'XYZ')
>>> ar
bytearray(b'XYZ')
>>> ar2 = ar[0:2]
>>> ar2
bytearray(b'XY')
>>> ar[0] = 32 # we modify `a`
>>> ar
bytearray(b' YZ')
>>> ar2 # `ar2` did not change
bytearray(b'XY')
But there are types for whom it is not the case; for example:
>>> ar = bytearray(b'XYZ')
>>> view = memoryview(ar)
>>> view
<memory at 0x...>
>>> view.tobytes()
b'XYZ'
>>> view2 = view[0:2]
>>> view2
<memory at 0x...>
>>> view2.tobytes()
b'XY'
>>> view[0] = 32 # this statement modifies both `view` and `view2`, and also `ar`!
>>> view.tobytes()
b' YZ'
>>> view2.tobytes()
b' Y'
>>> ar
bytearray(b' YZ')
Is this the same, in terms of memory usage, as using range() as in the following example?
range()
(or, in Python 2, xrange()
) is another story, as it does not store its items, but only the range limits (i.e., start and stop) and the optional step:
>>> range(1, 14, 2) # items 1, 3, 5, 7, 9, 11, 13 are not stored in memory
range(1, 14, 2)
>>> range(1000000000000000000000) # it does not take zillion bytes of memory :-)
range(0, 1000000000000000000000)