What does this notation do for lists in Python: "someList[:]"?
Asked Answered
S

6

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?

Sob answered 30/4, 2015 at 9:15 Comment(5)
are you referring to any specific language?Gardy
possible duplicate of How to clone or copy a list in Python?Shoon
possible duplicate of Explain Python's slice notationDeicer
It's not a duplicate of either question, although both contain an implicit answer.Heda
You may check my question: #29884768 [:] helped me solve my problem.Swisher
T
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.

Tetraploid answered 30/4, 2015 at 9:18 Comment(3)
Thanks, Frerich, I get it now. In those cases I came across [:] was indeed used for making a copy of a list.Sob
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.Timbal
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.Moton
P
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!

Pi answered 30/4, 2015 at 9:30 Comment(7)
"(for mutable objects...)": to be clear, b = a works exactly the same way if a is mutable or if a is immutable.Elwandaelwee
I think the easiest way, the prettiest, the best way is fairly subjective (and I disagree, I like list(a) better than a[:]).Tetraploid
@FrerichRaabe Yes, it's willingly subjective, that's why I used that much superlatives, and the smiley to emphasize thisPi
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.Throng
I use to know this 6-7 years ago! LolHallow
list also has a copy method since Python 3.3.Gibber
@Gibber Thanks, I've forgotten this one, and after some tests, it's the fastest way!Pi
K
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
Kermitkermy answered 30/4, 2015 at 9:18 Comment(0)
N
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)

Neediness answered 30/4, 2015 at 9:27 Comment(0)
S
-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.

Sheena answered 7/6, 2022 at 1:8 Comment(0)
P
-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']

Puppet answered 13/4, 2018 at 9:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.