append data-structures extend list python

What is the difference between Python’s list methods append and extend?


What’s the difference between the list methods append() and extend()?



    append appends a specified object at the end of the list:

    >>> x = [1, 2, 3]
    >>> x.append([4, 5])
    >>> print(x)
    [1, 2, 3, [4, 5]]

    extend extends the list by appending elements from the specified iterable:

    >>> x = [1, 2, 3]
    >>> x.extend([4, 5])
    >>> print(x)
    [1, 2, 3, 4, 5]


    • 162

      What is the difference between extend and simply using the addition operator – in the above example, x = x + [4, 5]?

      – Rohan

      May 29, 2017 at 22:10

    • 391

      Actually there’s a big differencex + [4, 5] gives you a new list assigned to x – x.extend() mutates the original list. I elaborate in my answer here below.

      Jul 17, 2017 at 17:14

    • 7

      @AaronHall @Rohan but it is same as x += [4,5].

      Dec 13, 2018 at 14:54

    • 2

      The keyword when using append is Object. If you try to use extend and you pass in a dictionary, it will append the key, and not the whole hash to the end of the array.

      – Anthony

      Mar 15, 2019 at 14:53

    • 1

      @Rohan, the time complexity of x = x + [4, 5] would be O(len(x) + len([4,5])) where as extend has the time complexity of O(len([4, 5]))

      Jul 22, 2020 at 16:20


    append adds an element to a list. extend concatenates the first list with another list/iterable.

    >>> xs = ['A', 'B']
    >>> xs
    ['A', 'B']
    >>> xs.append("D")
    >>> xs
    ['A', 'B', 'D']
    >>> xs.append(["E", "F"])
    >>> xs
    ['A', 'B', 'D', ['E', 'F']]
    >>> xs.insert(2, "C")
    >>> xs
    ['A', 'B', 'C', 'D', ['E', 'F']]
    >>> xs.extend(["G", "H"])
    >>> xs
    ['A', 'B', 'C', 'D', ['E', 'F'], 'G', 'H']



      What is the difference between the list methods append and extend?

      • append adds its argument as a single element to the end of a list. The length of the list itself will increase by one.
      • extend iterates over its argument adding each element to the list, extending the list. The length of the list will increase by however many elements were in the iterable argument.


      The list.append method appends an object to the end of the list.


      Whatever the object is, whether a number, a string, another list, or something else, it gets added onto the end of my_list as a single entry on the list.

      >>> my_list
      ['foo', 'bar']
      >>> my_list.append('baz')
      >>> my_list
      ['foo', 'bar', 'baz']

      So keep in mind that a list is an object. If you append another list onto a list, the first list will be a single object at the end of the list (which may not be what you want):

      >>> another_list = [1, 2, 3]
      >>> my_list.append(another_list)
      >>> my_list
      ['foo', 'bar', 'baz', [1, 2, 3]]
                           #^^^^^^^^^--- single item at the end of the list.


      The list.extend method extends a list by appending elements from an iterable:


      So with extend, each element of the iterable gets appended onto the list. For example:

      >>> my_list
      ['foo', 'bar']
      >>> another_list = [1, 2, 3]
      >>> my_list.extend(another_list)
      >>> my_list
      ['foo', 'bar', 1, 2, 3]

      Keep in mind that a string is an iterable, so if you extend a list with a string, you’ll append each character as you iterate over the string (which may not be what you want):

      >>> my_list.extend('baz')
      >>> my_list
      ['foo', 'bar', 1, 2, 3, 'b', 'a', 'z']

      Operator Overload, __add__ (+) and __iadd__ (+=)

      Both + and += operators are defined for list. They are semantically similar to extend.

      my_list + another_list creates a third list in memory, so you can return the result of it, but it requires that the second iterable be a list.

      my_list += another_list modifies the list in-place (it is the in-place operator, and lists are mutable objects, as we’ve seen) so it does not create a new list. It also works like extend, in that the second iterable can be any kind of iterable.

      Don’t get confused – my_list = my_list + another_list is not equivalent to += – it gives you a brand new list assigned to my_list.

      Time Complexity

      Append has (amortized) constant time complexity, O(1).

      Extend has time complexity, O(k).

      Iterating through the multiple calls to append adds to the complexity, making it equivalent to that of extend, and since extend’s iteration is implemented in C, it will always be faster if you intend to append successive items from an iterable onto a list.

      Regarding “amortized” – from the list object implementation source:

          /* This over-allocates proportional to the list size, making room
           * for additional growth.  The over-allocation is mild, but is
           * enough to give linear-time amortized behavior over a long
           * sequence of appends() in the presence of a poorly-performing
           * system realloc().

      This means that we get the benefits of a larger than needed memory reallocation up front, but we may pay for it on the next marginal reallocation with an even larger one. Total time for all appends is linear at O(n), and that time allocated per append, becomes O(1).


      You may wonder what is more performant, since append can be used to achieve the same outcome as extend. The following functions do the same thing:

      def append(alist, iterable):
          for item in iterable:
      def extend(alist, iterable):

      So let’s time them:

      import timeit
      >>> min(timeit.repeat(lambda: append([], "abcdefghijklmnopqrstuvwxyz")))
      >>> min(timeit.repeat(lambda: extend([], "abcdefghijklmnopqrstuvwxyz")))

      Addressing a comment on timings

      A commenter said:

      Perfect answer, I just miss the timing of comparing adding only one element

      Do the semantically correct thing. If you want to append all elements in an iterable, use extend. If you’re just adding one element, use append.

      Ok, so let’s create an experiment to see how this works out in time:

      def append_one(a_list, element):
      def extend_one(a_list, element):
          """creating a new list is semantically the most direct
          way to create an iterable to give to extend"""
      import timeit

      And we see that going out of our way to create an iterable just to use extend is a (minor) waste of time:

      >>> min(timeit.repeat(lambda: append_one([], 0)))
      >>> min(timeit.repeat(lambda: extend_one([], 0)))

      We learn from this that there’s nothing gained from using extend when we have only one element to append.

      Also, these timings are not that important. I am just showing them to make the point that, in Python, doing the semantically correct thing is doing things the Right Way™.

      It’s conceivable that you might test timings on two comparable operations and get an ambiguous or inverse result. Just focus on doing the semantically correct thing.


      We see that extend is semantically clearer, and that it can run much faster than append, when you intend to append each element in an iterable to a list.

      If you only have a single element (not in an iterable) to add to the list, use append.


      • 1

        @Aaron Hall One small comment in algorithm for timing. “extend_one” may return “slightly wrong” time because the creation of a list is also involved. Probably better is to create the items as variables (ex1 = 0 and ex2 = [0]) and pass these variables, if you want to be more strict.

        Mar 31, 2018 at 18:06

      • 22

        Perfect answer indeed. What about performance of l1 += l2 vs l1.extend(l2)?

        Apr 23, 2018 at 3:54

      • 11

        @Jean-FrancoisT.: l1 += l2 and l1.extend(l2) ultimately execute the same code (the list_extend function in listobject.c). The only differences are: 1. += reassigns l1 (to itself for lists, but the reassignment supports immutable types that aren’t the same object after), which makes it illegal if l1 is actually an attribute of an immutable object; for example, t = ([],), t[0] += lst would fail, while t[0].extend(lst) would work. 2. l1 += l2 uses dedicated bytecodes, while l1.extend(l2) uses generalized method dispatch; this makes += faster than extend.

        Aug 17, 2018 at 19:10

      • 3

        The fact that += must reassign l1 does mean that in some cases, the slower dispatch of extend is partially or wholly made up for by not assigning back to the left hand side. For example, if the list is an attribute of an object, self.l1 += l2 and self.l1.extend(l2) have identical performance on my Python 3.6 install, simply because real operation is more like self.l1 = self.l1.__iadd__(l2), which means it must perform a moderately expensive STORE_ATTR that self.l1.extend(l2) doesn’t have to.

        Aug 17, 2018 at 19:20

      • 2

        Simple comparison in local tests: For a local variable (so the += is just using STORE_FAST, which is super cheap), where the value being added is an existing list with one item in it, with the operation repeated 1000 times, += took about 33 ns on average, while extend took 78 ns, a difference of 45 ns. If l1 is a global (requires more expensive STORE_GLOBAL), the difference narrows to 17 ns. If l1 is actually local.l1 (requires even more expensive STORE_ATTR), there is no meaningful difference between += and extend (timings roughly identical; extend sometimes wins).

        Aug 17, 2018 at 19:32