Even though using .append requires a method  call it's actually slightly more efficient than using the augmented assignment operator, +=.
But there's an even better reason to use .append: you can do it when the list you're appending to isn't in the local scope, since it's just calling the method of an object in an outer scope, whereas you cannot perform assignments on objects that aren't in the local scope unless you declare them as global (or nonlocal), a practice which is generally best to avoid.
Here's an example:
mat = []
def test_append():
    for i in range(10):
        #mat += [i]
        mat.append(i)
def test_iadd():
    for i in range(10):
        mat += [i]
test_append()
print(mat)
test_iadd()
print(mat)
output
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Traceback (most recent call last):
  File "./qtest.py", line 29, in <module>
    test_iadd()
  File "./qtest.py", line 25, in test_iadd
    mat += [i]
UnboundLocalError: local variable 'mat' referenced before assignment
Of course, we can pass mat as an argument to the function:
mat = []
def test_append():
    for i in range(10):
        #mat += [i]
        mat.append(i)
def test_iadd2(mat):
    for i in range(10):
        mat += [i]
test_append()
print(mat)
test_iadd2(mat)
print(mat)
output
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
One reason that test_iadd2 is slower is that it has to construct a new [i] list on every loop. 
FWIW, here's the bytecode:
test_append
 21           0 SETUP_LOOP              33 (to 36)
              3 LOAD_GLOBAL              0 (range)
              6 LOAD_CONST               1 (10)
              9 CALL_FUNCTION            1
             12 GET_ITER            
        >>   13 FOR_ITER                19 (to 35)
             16 STORE_FAST               0 (i)
 23          19 LOAD_GLOBAL              1 (mat)
             22 LOAD_ATTR                2 (append)
             25 LOAD_FAST                0 (i)
             28 CALL_FUNCTION            1
             31 POP_TOP             
             32 JUMP_ABSOLUTE           13
        >>   35 POP_BLOCK           
        >>   36 LOAD_CONST               0 (None)
             39 RETURN_VALUE        
test_iadd2
 26           0 SETUP_LOOP              33 (to 36)
              3 LOAD_GLOBAL              0 (range)
              6 LOAD_CONST               1 (10)
              9 CALL_FUNCTION            1
             12 GET_ITER            
        >>   13 FOR_ITER                19 (to 35)
             16 STORE_FAST               1 (i)
 27          19 LOAD_FAST                0 (mat)
             22 LOAD_FAST                1 (i)
             25 BUILD_LIST               1
             28 INPLACE_ADD         
             29 STORE_FAST               0 (mat)
             32 JUMP_ABSOLUTE           13
        >>   35 POP_BLOCK           
        >>   36 LOAD_CONST               0 (None)
             39 RETURN_VALUE        
The above bytecode dump was produced using the dis module:
from dis import dis
mat = []
def test_append():
    for i in range(10):
        #mat += [i]
        mat.append(i)
def test_iadd2(mat):
    for i in range(10):
        mat += [i]
print('test_append')
dis(test_append)
print('\ntest_iadd2')
dis(test_iadd2)