Python append() vs. + operator on lists, why do these give different results?

145,476

Solution 1

To explain "why":

The + operation adds the array elements to the original array. The array.append operation inserts the array (or any object) into the end of the original array, which results in a reference to self in that spot (hence the infinite recursion).

The difference here is that the + operation acts specific when you add an array (it's overloaded like others, see this chapter on sequences) by concatenating the element. The append-method however does literally what you ask: append the object on the right-hand side that you give it (the array or any other object), instead of taking its elements.

An alternative

Use extend() if you want to use a function that acts similar to the + operator (as others have shown here as well). It's not wise to do the opposite: to try to mimic append with the + operator for lists (see my earlier link on why).

Little history

For fun, a little history: the birth of the array module in Python in February 1993. it might surprise you, but arrays were added way after sequences and lists came into existence.

Solution 2

The concatenation operator + is a binary infix operator which, when applied to lists, returns a new list containing all the elements of each of its two operands. The list.append() method is a mutator on list which appends its single object argument (in your specific example the list c) to the subject list. In your example this results in c appending a reference to itself (hence the infinite recursion).

An alternative to '+' concatenation

The list.extend() method is also a mutator method which concatenates its sequence argument with the subject list. Specifically, it appends each of the elements of sequence in iteration order.

An aside

Being an operator, + returns the result of the expression as a new value. Being a non-chaining mutator method, list.extend() modifies the subject list in-place and returns nothing.

Arrays

I've added this due to the potential confusion which the Abel's answer above may cause by mixing the discussion of lists, sequences and arrays. Arrays were added to Python after sequences and lists, as a more efficient way of storing arrays of integral data types. Do not confuse arrays with lists. They are not the same.

From the array docs:

Arrays are sequence types and behave very much like lists, except that the type of objects stored in them is constrained. The type is specified at object creation time by using a type code, which is a single character.

Solution 3

append is appending an element to a list. if you want to extend the list with the new list you need to use extend.

>>> c = [1, 2, 3]
>>> c.extend(c)
>>> c
[1, 2, 3, 1, 2, 3]

Solution 4

Python lists are heterogeneous that is the elements in the same list can be any type of object. The expression: c.append(c) appends the object c what ever it may be to the list. In the case it makes the list itself a member of the list.

The expression c += c adds two lists together and assigns the result to the variable c. The overloaded + operator is defined on lists to create a new list whose contents are the elements in the first list and the elements in the second list.

So these are really just different expressions used to do different things by design.

Solution 5

The method you're looking for is extend(). From the Python documentation:

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

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

list.insert(i, x)
    Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).
Share:
145,476
ooboo
Author by

ooboo

Updated on June 15, 2020

Comments

  • ooboo
    ooboo almost 4 years

    Why do these two operations (append() resp. +) give different results?

    >>> c = [1, 2, 3]
    >>> c
    [1, 2, 3]
    >>> c += c
    >>> c
    [1, 2, 3, 1, 2, 3]
    >>> c = [1, 2, 3]
    >>> c.append(c)
    >>> c
    [1, 2, 3, [...]]
    >>> 
    

    In the last case there's actually an infinite recursion. c[-1] and c are the same. Why is it different with the + operation?

    • Aisah Hamzah
      Aisah Hamzah over 14 years
      with all due respect to a viable new question: I rolled back to the original question to keep it clean (1 question per thread, see SO FAQ). Please ask a new one or ask follow-up questions inside the comment-threads below each answer. Note: your edits are not lost, click the history and you can copy/paste it into a new question.
    • Ciro Santilli OurBigBook.com
      Ciro Santilli OurBigBook.com about 9 years
    • Sharif Chowdhury
      Sharif Chowdhury over 6 years
      it seems that it gives different ans, but not like that. If you want to add a value using + operator you have o use [] sign. c += [c] will give you same result as append.
    • trustory
      trustory over 4 years
      @SharifChowdhury I believe you will get the same result
  • jathanism
    jathanism over 14 years
    +1 because I always upvote accurate information. Links to official docs are always a plus!
  • SilentGhost
    SilentGhost over 14 years
    I thought it's quite clear why the results are different, because operations are not the same! if it would appear that + and extend produce different results that we'd have something to think about.
  • Beni Cherniavsky-Paskin
    Beni Cherniavsky-Paskin over 14 years
    Another part of "why": sane people expect + to be symmetric: concatenate list with list.
  • Aisah Hamzah
    Aisah Hamzah over 14 years
    +1, Good point Beni (while I could consider it just as "sane" to say "the object on the rh side is appended to the array on lh side", but personally find the current behavior more sensible).
  • user1066101
    user1066101 over 14 years
    +1: Why I dislike "why" questions: append and + are different. That's why. I like this answer because offers what do do that makes more sense.
  • Aisah Hamzah
    Aisah Hamzah over 14 years
    Isn't this site about answering the questions asked? People ask why PHP is called PHP and why __lt__ could not be overloaded in Python (nowadays it can). Why-questions are the most essential ones but often the trickiest to answer: they ask for the essence, not for a pointer to the manual. And of course: if you dislike a question (I dislike most), then don't answer ;-)
  • ephemient
    ephemient over 14 years
    For further demonstration, maybe show c += [c] and c.append(c[:]) too.
  • user1066101
    user1066101 over 14 years
    @Abel: Why is a+b != a*b? They're different operations. That's the answer. "Why" isn't as helpful as other questions, like "How can I append properly?" Or "What's wrong with this append that leads to infinite recursion?" Questions of the form "What do I do to X" or "What went wrong when I did X"? Or "What should I do instead of X" will also help someone learn, but will provide focused, usable, actionable answers.
  • Aisah Hamzah
    Aisah Hamzah over 14 years
    Interesting side discussion, not sure if we should... but...: If you ask "how can I do X", you answer obj.X or obj+X. The more elaborate answerer will also explain why you should choose either, to teach the asker how to think about it. Yes, I agree, what, how etc can give very simple, very clear answers, most of the time. why is often called the only question with infinite answers.But it teaches us to think. How do we live is boring (imo), why do we live is much more intriguing. Python started out with the question "why do we need a new language". The answer was the language.
  • user3512680
    user3512680 over 4 years
    if an element is single string, e.g. s = 'word', l = ['this', 'is']. Then l.append(s) and l+s should be the same. Am I correct?
  • Abhi
    Abhi over 2 years
    It is not same, to get same answer, you should use l+[s], otherwise it will throw 'TypeError: can only concatenate list (not "str") to list'.
  • juanpa.arrivillaga
    juanpa.arrivillaga over 2 years
    Why are you linking to the array.array docs??
  • Aisah Hamzah
    Aisah Hamzah over 2 years
    @juanpa.arrivillaga, the links go to the array.html pages of the reference docs. The #array.array... you see in the links are the id of the item in that page. The topic is on arrays, so yeah, that's really all there is to it: convenience links to the docs (of 12yr ago).
  • juanpa.arrivillaga
    juanpa.arrivillaga over 2 years
    @Abel although the array.array and list types work identically in this particular regard, the question was about list objects, not array.array objects, unless something was changed in an edit? Note, you cannot actually get the equivalent of [1, 2, 3, [...]] with array.array objects, it would throw a type error if you did my_array.append(my_array)
  • Aisah Hamzah
    Aisah Hamzah over 2 years
    @juanpa.arrivillaga, Ah wait, lists vs arrays. I’ll check tomorrow to update my answer a little, I see now, tx!
  • juanpa.arrivillaga
    juanpa.arrivillaga over 2 years
    @Abel yeah, unfortunately, the modern docs kind merged the "mutable sequence" operations into one table summarizing their operations. But you can also link to the tutorial which documents some of these operations for list objects specifically