32

I sometimes get across this way of printing or returning a list - someList[:]. I don't see why people use it, as it returns the full list.

Why not simply write someList, whithout the [:] part?

smci
  • 32,567
  • 20
  • 113
  • 146
Petr S
  • 303
  • 3
  • 7
  • are you referring to any specific language? – Artur Peniche Apr 30 '15 at 09:16
  • 5
    possible duplicate of [How to clone or copy a list in Python?](http://stackoverflow.com/questions/2612802/how-to-clone-or-copy-a-list-in-python) – Łukasz Rogalski Apr 30 '15 at 09:17
  • 5
    possible duplicate of [Explain Python's slice notation](http://stackoverflow.com/questions/509211/explain-pythons-slice-notation) – LittlePanda Apr 30 '15 at 09:29
  • 12
    It's not a duplicate of either question, although both contain an implicit answer. – Cephalopod Apr 30 '15 at 09:55
  • You may check my question: http://stackoverflow.com/questions/29884268/how-do-references-in-functions-work [:] helped me solve my problem. –  Apr 30 '15 at 10:48

6 Answers6

54

[:] creates a slice, usually used to get just a part of a list. Without any minimum/maximum index given, it creates a copy of the entire list. Here's a Python session demonstrating it:

>>> a = [1,2,3]
>>> b1 = a
>>> b2 = a[:]
>>> b1.append(50)
>>> b2.append(51)
>>> a
[1, 2, 3, 50]
>>> b1
[1, 2, 3, 50]
>>> b2
[1, 2, 3, 51]

Note how appending to b1 also appended the value to a. Appending to b2 however did not modify a, i.e. b2 is a copy.

Frerich Raabe
  • 90,689
  • 19
  • 115
  • 207
  • Thanks, Frerich, I get it now. In those cases I came across [:] was indeed used for making a copy of a list. – Petr S Apr 30 '15 at 09:32
  • 19
    It's probably worth mentioning that this creates a *shallow* copy of the list, so the pattern can run into problems if you have, eg, lists of lists. – sapi Apr 30 '15 at 09:55
  • 1
    From an "explicit is better than implicit" point of view, it might be better to ``import copy`` and using ``copy.copy(lst)`` instead. The slice notation doesn't hint at what it does and is hard to google. – Christian Aichinger May 01 '15 at 06:01
16

In python, when you do a = b, a doesn't take the value of b, but references the same value referenced by b. To see this, make:

>>> a = {'Test': 42}
>>> b = a
>>> b['Test'] = 24

What is now the value of a?

>>> a['Test']
24

It's similar with lists, so we must find a way to really copy a list, and not make a reference to it. One way could be to recreate the list copy = list(list1), or use the functions of the copy module. But, after all, the easiest way, the prettiest, the best way ( ;) ) for doing this, is to copy each value of the first list to the other, by doing copy = list1[:]. It uses the slices, here list1 is sliced from index 0 to index len(list1), so the whole list1 is returned!

Moreover, the slice method is slightly faster: using the time.clock() method to measure the mean execution time of 1000 assignment of lists, each one containing 10000 random integers, with slices, constructor and deepcopy, the results show that the slices are 15% faster than the constructor method, and deepcopy is 4 times slower. However, this gain of time is negligible while using small lists: thus, using copy = list(list_to_copy) or copy = list_to_copy[:] is up to the developer's preferences.

Finally, we often forget the list.copy method, which seems to be the faster! In fact, it's even 13% faster than the slice method!

Spirine
  • 1,837
  • 1
  • 16
  • 28
  • 1
    "(for mutable objects...)": to be clear, `b = a` works exactly the same way if `a` is mutable or if `a` is immutable. – DSM Apr 30 '15 at 11:20
  • I think `the easiest way, the prettiest, the best way` is fairly subjective (and I disagree, I like `list(a)` better than `a[:]`). – Frerich Raabe Apr 30 '15 at 12:20
  • 1
    @FrerichRaabe Yes, it's willingly subjective, that's why I used that much superlatives, and the smiley to emphasize this – Spirine Apr 30 '15 at 12:34
  • 1
    The answer is wrong IMHO. `a = b` doesn't create a reference to _b_ but to the value referenced by _b_. After the assignment both names reference the same value. In fact every name in Python references a value, so even copying the list before assignment leads to a reference — to the new list object. Objectively speaking `list(L)` is easier to look up in the docs than `L[:]` and it is much more flexible because `L` can be anything that's _iterable_ and not just objects that support slicing. It works even with objects that don't implement slicing at all. – BlackJack Apr 30 '15 at 12:44
  • I use to know this 6-7 years ago! Lol – Radu Apr 30 '15 at 17:24
  • 1
    `list` also has a `copy` method since Python 3.3. – Veedrac Apr 30 '15 at 20:04
  • 1
    @Veedrac Thanks, I've forgotten this one, and after some tests, it's the fastest way! – Spirine Apr 30 '15 at 21:43
8

To create a copy of a list instead of passing by reference, as Python does. Use next two example to understand the difference.

Example:

# Passing by reference
SomeListA = [1, 2, 3]
SomeListB = [2, 3, 4]
SomeListB = SomeListA
SomeListA[2] = 5
print SomeListB
print SomeListA

# Using slice
SomeListA = [1, 2, 3]
SomeListB = [2, 3, 4]
SomeListB = SomeListA[:]
SomeListA[2] = 5
print SomeListB
print SomeListA
Neithrik
  • 2,002
  • 2
  • 20
  • 33
4

When you need to modify the list and you don't want to change the list and create another list you use

y = [1,2,3]
x = y[:]

and you can do a lot of changes to the list but the origin list will be in (y) and the modified in (x)

-1

#Here is a simpler way for beginners to understand:

list16 = [1,2,3,4,5,6]
list17 = list16[:] 

#^Identifying that 'list17' is a copy of 'list16' and not list16 directly

list17[0] = 10

#^ Making an alteration in the new copied list

print(list17)
print(list16)
= [10,2,3,4,5,6]
= [1,2,3,4,5,6]

#Printing the lists so that you can see what is happening. I created a copy of the list and altered it without changing the original list at all.

-2

There are 2 copies available. 1) Deep Copy 2) Shallow Copy.
1) Deep Copy is you just copy the values
list = ['abc',123,'xyz']
list1 = copy.deepcopy(list) or list1 = list[:]

2) Shallow Copy is you just reference to the varible
list2 = copy.copy(list) or list2 = list

When you modify something on list2 it get effected in list also as it is referenced. list1.append(456)
list2.append('789')
print "list: %s" %list
print "list1: %s" %list1
print "list2: %s" %list2
ans:
list : ['abc',123,'xyz','789']
list1 : ['abc',123,'xyz',456]
list2 : ['abc',123,'xyz','789']

Kit
  • 1
  • 1