Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: understanding difference between append and extend

The code below will not run in its current state. However, if I change sum_vec.extend( vec1[i] + vec2[i] ) to sum_vec.append( vec1[i] + vec2[i] ) it works just fine. I understand the basic different between append and extend, but I don't understand why the code doesn't work if I use extend.

def addVectors(v1, v2):

    vec1 = list(v1)
    vec2 = list(v2)
    sum_vec = []
    vec1_len = len(vec1)
    vec2_len = len(vec2)
    min_len = min( vec1_len, vec2_len )

    # adding up elements pointwise
    if vec1_len == 0 and vec2_len == 0:
        return sum_vec
    else:
        for i in xrange(0, min_len):
            sum_vec.extend( vec1[i] + vec2[i] )

    # in case one vector is longer than the other
    if vec1_len != vec2_len:
        if vec1_len > vec2_len:
            sum_vec.extend( vec1[min_len : vec1_len] )
        else:
            sum_vec.extend( vec2[min_len : vec2_len] ) 
    print sum_vec
    return sum_vec

v1 = [1,3,5]
v2 = [2,4,6,8,10]
addVectors(v1,v2)
like image 642
TheRealFakeNews Avatar asked Apr 08 '15 11:04

TheRealFakeNews


3 Answers

As others have pointed out, extend takes an iterable (such as a list, tuple or string), and adds each element of the iterable to the list one at a time, while append adds its argument to the end of the list as a single item. The key thing to note is that extend is a more efficient version of calling append multiple times.

a = [1,2]
b = [1,2]

a.extend([3, 4])
for x in [3, 4]:
    b.append(x)

assert a == b

append can take an iterable as its argument, but it treats it as a single object:

a = [1,2]
a.append([3,4])
assert a == [1, 2, [3, 4]]  # not [1, 2, 3, 4]
like image 67
chepner Avatar answered Oct 20 '22 01:10

chepner


You can read the documentation on list:

list.append adds a single item to the end of your list:

Add an item to the end of the list; equivalent to a[len(a):] = [x].

list.extend uses an iterable and adds all of it's elements to the end of your list:

Extend the list by appending all the items in the given list; equivalent to a[len(a):] = L.

You need to use:

sum_vec.extend([vec1[i] + vec2[i]]) # note that a list is created

That way an iterable with a single item (vec1[i] + vec2[i]) is passed. But list.append is more suitable when you're always adding a single item.

like image 37
Reut Sharabani Avatar answered Oct 20 '22 02:10

Reut Sharabani


When you run your code, you get an exception like this:

Traceback (most recent call last):
  File ".../stack.py", line 28, in <module>
    addVectors(v1,v2)
  File ".../stack.py", line 15, in addVectors
    sum_vec.extend( vec1[i] + vec2[i] )
TypeError: 'int' object is not iterable

In other words, the extend method expects an iterable as argument. However append method gets an item as argument.

Here is a small example of the difference between extend and append:

l = [1, 2, 3, 4]
m = [10, 11]
r = list(m)
m.append(l)
r.extend(l)

print(m)
print(r)

Output:

[10, 11, [1, 2, 3, 4]]
[10, 11, 1, 2, 3, 4]
like image 33
aldeb Avatar answered Oct 20 '22 03:10

aldeb