What is the difference between:
some_list1 = []
some_list1.append("something")
and
some_list2 = [] some_list2 += ["something"]
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
For your case the only difference is performance: append is twice as fast.
Python 3.0 (r30:67507, Dec 3 2008, 20:14:27) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import timeit
>>> timeit.Timer('s.append("something")', 's = []').timeit()
0.20177424499999999
>>> timeit.Timer('s += ["something"]', 's = []').timeit()
0.41192320500000079
Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import timeit
>>> timeit.Timer('s.append("something")', 's = []').timeit()
0.23079359499999999
>>> timeit.Timer('s += ["something"]', 's = []').timeit()
0.44208112500000141
In general case append will add one item to the list, while += will copy all elements of right-hand-side list into the left-hand-side list.
Update: perf analysis
Comparing bytecodes we can assume that append version wastes cycles in LOAD_ATTR + CALL_FUNCTION, and += version — in BUILD_LIST. Apparently BUILD_LIST outweighs LOAD_ATTR + CALL_FUNCTION.
>>> import dis
>>> dis.dis(compile("s = []; s.append('spam')", '', 'exec'))
1 0 BUILD_LIST 0
3 STORE_NAME 0 (s)
6 LOAD_NAME 0 (s)
9 LOAD_ATTR 1 (append)
12 LOAD_CONST 0 ('spam')
15 CALL_FUNCTION 1
18 POP_TOP
19 LOAD_CONST 1 (None)
22 RETURN_VALUE
>>> dis.dis(compile("s = []; s += ['spam']", '', 'exec'))
1 0 BUILD_LIST 0
3 STORE_NAME 0 (s)
6 LOAD_NAME 0 (s)
9 LOAD_CONST 0 ('spam')
12 BUILD_LIST 1
15 INPLACE_ADD
16 STORE_NAME 0 (s)
19 LOAD_CONST 1 (None)
22 RETURN_VALUE
We can improve performance even more by removing LOAD_ATTR overhead:
>>> timeit.Timer('a("something")', 's = []; a = s.append').timeit()
0.15924410999923566
Method 2
In the example you gave, there is no difference, in terms of output, between append and +=. But there is a difference between append and + (which the question originally asked about).
>>> a = []
>>> id(a)
11814312
>>> a.append("hello")
>>> id(a)
11814312
>>> b = []
>>> id(b)
11828720
>>> c = b + ["hello"]
>>> id(c)
11833752
>>> b += ["hello"]
>>> id(b)
11828720
As you can see, append and += have the same result; they add the item to the list, without producing a new list. Using + adds the two lists and produces a new list.
Method 3
>>> a=[] >>> a.append([1,2]) >>> a [[1, 2]] >>> a=[] >>> a+=[1,2] >>> a [1, 2]
See that append adds a single element to the list, which may be anything. +=[] joins the lists.
Method 4
+= is an assignment. When you use it you’re really saying ‘some_list2= some_list2+[‘something’]’. Assignments involve rebinding, so:
l= []
def a1(x):
l.append(x) # works
def a2(x):
l= l+[x] # assign to l, makes l local
# so attempt to read l for addition gives UnboundLocalError
def a3(x):
l+= [x] # fails for the same reason
The += operator should also normally create a new list object like list+list normally does:
>>> l1= []
>>> l2= l1
>>> l1.append('x')
>>> l1 is l2
True
>>> l1= l1+['x']
>>> l1 is l2
False
However in reality:
>>> l2= l1 >>> l1+= ['x'] >>> l1 is l2 True
This is because Python lists implement __iadd__() to make a += augmented assignment short-circuit and call list.extend() instead. (It’s a bit of a strange wart this: it usually does what you meant, but for confusing reasons.)
In general, if you’re appending/extended an existing list, and you want to keep the reference to the same list (instead of making a new one), it’s best to be explicit and stick with the append()/extend() methods.
Method 5
some_list2 += ["something"]
is actually
some_list2.extend(["something"])
for one value, there is no difference.
Documentation states, that:
s.append(x)same ass[len(s):len(s)] = [x]
s.extend(x)same ass[len(s):len(s)] = x
Thus obviously s.append(x) is same as s.extend([x])
Method 6
The difference is that concatenate will flatten the resulting list, whereas append will keep the levels intact:
So for example with:
myList = [ ] listA = [1,2,3] listB = ["a","b","c"]
Using append, you end up with a list of lists:
>> myList.append(listA) >> myList.append(listB) >> myList [[1,2,3],['a','b','c']]
Using concatenate instead, you end up with a flat list:
>> myList += listA + listB >> myList [1,2,3,"a","b","c"]
Method 7
The performance tests here are not correct:
- You shouldn’t run the profile only once.
- If comparing
appendvs.+=[]a number of times, you should declareappendas a local function. - Time results are different on different python versions: 64- and 32-bit.
e.g.
timeit.Timer('for i in xrange(100): app(i)', 's = [] ; app = s.append').timeit()
Good tests can be found here: Python list append vs. +=[]
Method 8
In addition to the aspects described in the other answers, append and +[] have very different behaviors when you’re trying to build a list of lists.
>>> list1=[[1,2],[3,4]] >>> list2=[5,6] >>> list3=list1+list2 >>> list3 [[1, 2], [3, 4], 5, 6] >>> list1.append(list2) >>> list1 [[1, 2], [3, 4], [5, 6]]
list1+[‘5′,’6’] adds ‘5’ and ‘6’ to the list1 as individual elements. list1.append([‘5′,’6’]) adds the list [‘5′,’6’] to the list1 as a single element.
Method 9
The rebinding behaviour mentioned in other answers does matter in certain circumstances:
>>> a = ([],[]) >>> a[0].append(1) >>> a ([1], []) >>> a[1] += [1] Traceback (most recent call last): File "<interactive input>", line 1, in <module> TypeError: 'tuple' object does not support item assignment
That’s because augmented assignment always rebinds, even if the object was mutated in-place. The rebinding here happens to be a[1] = *mutated list*, which doesn’t work for tuples.
Method 10
“+” does not mutate the list
.append() mutates the old list
Method 11
let’s take an example first
list1=[1,2,3,4] list2=list1 (that means they points to same object) if we do list1=list1+[5] it will create a new object of list print(list1) output [1,2,3,4,5] print(list2) output [1,2,3,4] but if we append then list1.append(5) no new object of list created print(list1) output [1,2,3,4,5] print(list2) output [1,2,3,4,5] extend(list) also do the same work as append it just append a list instead of a single variable
Method 12
The append() method adds a single item to the existing list
some_list1 = []
some_list1.append("something")
So here the some_list1 will get modified.
Updated:
Whereas using + to combine the elements of lists (more than one element) in the existing list similar to the extend (as corrected by Flux).
some_list2 = [] some_list2 += ["something"]
So here the some_list2 and [“something”] are the two lists that are combined.
Method 13
As of today and Python 3.6, the results provided by @Constantine are no longer the same.
Python 3.6.10 |Anaconda, Inc.| (default, May 8 2020, 02:54:21)
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import timeit
>>> timeit.Timer('s.append("something")', 's = []').timeit()
0.0447923709944007
>>> timeit.Timer('s += ["something"]', 's = []').timeit()
0.04335783299757168
It seems that append and += now have an equal performance, whereas the compilation differences haven’t changed at all:
>>> import dis
>>> dis.dis(compile("s = []; s.append('spam')", '', 'exec'))
1 0 BUILD_LIST 0
2 STORE_NAME 0 (s)
4 LOAD_NAME 0 (s)
6 LOAD_ATTR 1 (append)
8 LOAD_CONST 0 ('spam')
10 CALL_FUNCTION 1
12 POP_TOP
14 LOAD_CONST 1 (None)
16 RETURN_VALUE
>>> dis.dis(compile("s = []; s += ['spam']", '', 'exec'))
1 0 BUILD_LIST 0
2 STORE_NAME 0 (s)
4 LOAD_NAME 0 (s)
6 LOAD_CONST 0 ('spam')
8 BUILD_LIST 1
10 INPLACE_ADD
12 STORE_NAME 0 (s)
14 LOAD_CONST 1 (None)
16 RETURN_VALUE
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0