python – What is the difference between [:] and .copy()?

Question:

Faced such a situation, having a list:

a = [1, 2, 3]

I want to get a copy of it, making the new переменную unique so that it does not refer to the address of the old one. I know of two constructs that essentially do the same thing:

b = a[:]

and

b = a.copy()

Both of them are correct and will give the same result, but are there fundamental differences between them ?

Answer:

The list.copy() method was introduced in Python 3.3 . The reason for its introduction was to make the syntax more readable and because for other objects such as dict and set the .copy() method already existed and it would make sense to make it available for list as well.

Python handles these calls differently – a[:] is handled by slice , while a.copy() is handled by calling the appropriate method:

In [50]: import dis

In [51]: dis.dis("a.copy()")
  1           0 LOAD_NAME                0 (a)
              2 LOAD_ATTR                1 (copy)
              4 CALL_FUNCTION            0
              6 RETURN_VALUE

In [52]: dis.dis("a[:]")
  1           0 LOAD_NAME                0 (a)
              2 LOAD_CONST               0 (None)
              4 LOAD_CONST               0 (None)
              6 BUILD_SLICE              2
              8 BINARY_SUBSCR
             10 RETURN_VALUE

Which one works faster?

for 10.000.000 elements:

In [47]: lst = list(range(10**7))

In [48]: %timeit lst[:]
119 ms ± 1.65 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [49]: %timeit lst.copy()
119 ms ± 1.84 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

for 10.000 items:

In [53]: lst = list(range(10**4))

In [54]: %timeit lst.copy()
44.1 µs ± 602 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [55]: %timeit lst[:]
45.6 µs ± 3.23 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

for 100 elements:

In [62]: lst = list(range(100))

In [63]: %timeit lst.copy()
456 ns ± 19.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [64]: %timeit lst[:]
458 ns ± 22.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

those. in terms of speed, they are almost the same.

What is the preferred syntax?

I find a.copy() to be preferable because is explicit and clear, and besides that, if you have to replace a list ( list ) with a set ( set ) in the code, then the slicing syntax will not work for a set.


PS A lot of useful and related information can be found in the answers to a similar question in the English version of SO

Scroll to Top