Is i = i + n truly the same as i += n?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
6
down vote

favorite
2












One block of code works but the other does not. Which would make sense except the second block is the same as the first only with an operation written in shorthand. They are practically the same operation.



l = ['table']
i =


Version 1



for n in l:
i += n
print(i)


Output: ['t', 'a', 'b', 'l', 'e']



Version 2



for n in l:
i = i + n
print(i)


Output:




TypeError: can only concatenate list (not "str") to list




What is causing this strange error?










share|improve this question









New contributor




Luke Bakare is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.















  • 4




    No, not the same for lists. += extends a list. + concatenates two lists into a new list.
    – khelwood
    40 mins ago










  • "What is causing this strange error?" It's not an error. It's the behavior of an overloaded operator.
    – GreenMatt
    37 mins ago






  • 2




    Ideally, if you're using this idea in code, it's probably safer to use the append() and extend() methods for adding elements and concatenating lists, respectively, to avoid ambiguity like this.
    – Green Cloak Guy
    36 mins ago














up vote
6
down vote

favorite
2












One block of code works but the other does not. Which would make sense except the second block is the same as the first only with an operation written in shorthand. They are practically the same operation.



l = ['table']
i =


Version 1



for n in l:
i += n
print(i)


Output: ['t', 'a', 'b', 'l', 'e']



Version 2



for n in l:
i = i + n
print(i)


Output:




TypeError: can only concatenate list (not "str") to list




What is causing this strange error?










share|improve this question









New contributor




Luke Bakare is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.















  • 4




    No, not the same for lists. += extends a list. + concatenates two lists into a new list.
    – khelwood
    40 mins ago










  • "What is causing this strange error?" It's not an error. It's the behavior of an overloaded operator.
    – GreenMatt
    37 mins ago






  • 2




    Ideally, if you're using this idea in code, it's probably safer to use the append() and extend() methods for adding elements and concatenating lists, respectively, to avoid ambiguity like this.
    – Green Cloak Guy
    36 mins ago












up vote
6
down vote

favorite
2









up vote
6
down vote

favorite
2






2





One block of code works but the other does not. Which would make sense except the second block is the same as the first only with an operation written in shorthand. They are practically the same operation.



l = ['table']
i =


Version 1



for n in l:
i += n
print(i)


Output: ['t', 'a', 'b', 'l', 'e']



Version 2



for n in l:
i = i + n
print(i)


Output:




TypeError: can only concatenate list (not "str") to list




What is causing this strange error?










share|improve this question









New contributor




Luke Bakare is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











One block of code works but the other does not. Which would make sense except the second block is the same as the first only with an operation written in shorthand. They are practically the same operation.



l = ['table']
i =


Version 1



for n in l:
i += n
print(i)


Output: ['t', 'a', 'b', 'l', 'e']



Version 2



for n in l:
i = i + n
print(i)


Output:




TypeError: can only concatenate list (not "str") to list




What is causing this strange error?







python python-3.x






share|improve this question









New contributor




Luke Bakare is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Luke Bakare is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 40 mins ago









khelwood

28.3k63858




28.3k63858






New contributor




Luke Bakare is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 46 mins ago









Luke Bakare

333




333




New contributor




Luke Bakare is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Luke Bakare is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Luke Bakare is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







  • 4




    No, not the same for lists. += extends a list. + concatenates two lists into a new list.
    – khelwood
    40 mins ago










  • "What is causing this strange error?" It's not an error. It's the behavior of an overloaded operator.
    – GreenMatt
    37 mins ago






  • 2




    Ideally, if you're using this idea in code, it's probably safer to use the append() and extend() methods for adding elements and concatenating lists, respectively, to avoid ambiguity like this.
    – Green Cloak Guy
    36 mins ago












  • 4




    No, not the same for lists. += extends a list. + concatenates two lists into a new list.
    – khelwood
    40 mins ago










  • "What is causing this strange error?" It's not an error. It's the behavior of an overloaded operator.
    – GreenMatt
    37 mins ago






  • 2




    Ideally, if you're using this idea in code, it's probably safer to use the append() and extend() methods for adding elements and concatenating lists, respectively, to avoid ambiguity like this.
    – Green Cloak Guy
    36 mins ago







4




4




No, not the same for lists. += extends a list. + concatenates two lists into a new list.
– khelwood
40 mins ago




No, not the same for lists. += extends a list. + concatenates two lists into a new list.
– khelwood
40 mins ago












"What is causing this strange error?" It's not an error. It's the behavior of an overloaded operator.
– GreenMatt
37 mins ago




"What is causing this strange error?" It's not an error. It's the behavior of an overloaded operator.
– GreenMatt
37 mins ago




2




2




Ideally, if you're using this idea in code, it's probably safer to use the append() and extend() methods for adding elements and concatenating lists, respectively, to avoid ambiguity like this.
– Green Cloak Guy
36 mins ago




Ideally, if you're using this idea in code, it's probably safer to use the append() and extend() methods for adding elements and concatenating lists, respectively, to avoid ambiguity like this.
– Green Cloak Guy
36 mins ago












2 Answers
2






active

oldest

votes

















up vote
9
down vote



accepted










They don't have to be the same.



Using the + operator calls the method __add__ while using the += operator calls __iadd__. It is completey up to the object in question what happens when one of these methods is called.



If you use x += y but x does not provide an __iadd__ method, __add__ is used as a fallback, e.g. x = x + y happens.



In the case of lists, using l += iterable actually extends the list l with the elements of iterable. In your case, every character from the string (which is an iterable) is appended during the extend operation.



Demo 1: using __iadd__



>>> l = 
>>> l += 'table'
>>> l
['t', 'a', 'b', 'l', 'e']


Demo 2: using extend does the same



>>> l = 
>>> l.extend('table')
>>> l
['t', 'a', 'b', 'l', 'e']


Demo 3: adding a list and a string raises a TypeError.



>>> l = 
>>> l = l + 'table'
[...]
TypeError: can only concatenate list (not "str") to list


Not using += gives you the TypeError here because only __iadd__ implements the extending behavior.



Demo 4: common pitfall: += does not build a new list (note the identical ids)



>>> l = 
>>> id(l)
140359172117512
>>> l += [1, 2, 3]
>>> id(l)
140359172117512


... but the l = l + iterable syntax does.



>>> l = 
>>> id(l)
140359172142472
>>> l = l + [1, 2, 3]
>>> id(l)
140359172167560


In some cases, this can produce subtle bugs, because += mutates the original list, while
l = l + iterable builds a new list and reassigns the name l.



BONUS



Ned Batchelder's challenge to find this in the docs






share|improve this answer


















  • 1




    Thorough explanation. Thank you!
    – Luke Bakare
    29 mins ago

















up vote
0
down vote













If in the second case you cast the n to a list to avoid errors:



for n in l:
i = i + [n]
print(i)


you get



['table']


so they do different operations.






share|improve this answer




















    Your Answer





    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );






    Luke Bakare is a new contributor. Be nice, and check out our Code of Conduct.









     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52747784%2fis-i-i-n-truly-the-same-as-i-n%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    9
    down vote



    accepted










    They don't have to be the same.



    Using the + operator calls the method __add__ while using the += operator calls __iadd__. It is completey up to the object in question what happens when one of these methods is called.



    If you use x += y but x does not provide an __iadd__ method, __add__ is used as a fallback, e.g. x = x + y happens.



    In the case of lists, using l += iterable actually extends the list l with the elements of iterable. In your case, every character from the string (which is an iterable) is appended during the extend operation.



    Demo 1: using __iadd__



    >>> l = 
    >>> l += 'table'
    >>> l
    ['t', 'a', 'b', 'l', 'e']


    Demo 2: using extend does the same



    >>> l = 
    >>> l.extend('table')
    >>> l
    ['t', 'a', 'b', 'l', 'e']


    Demo 3: adding a list and a string raises a TypeError.



    >>> l = 
    >>> l = l + 'table'
    [...]
    TypeError: can only concatenate list (not "str") to list


    Not using += gives you the TypeError here because only __iadd__ implements the extending behavior.



    Demo 4: common pitfall: += does not build a new list (note the identical ids)



    >>> l = 
    >>> id(l)
    140359172117512
    >>> l += [1, 2, 3]
    >>> id(l)
    140359172117512


    ... but the l = l + iterable syntax does.



    >>> l = 
    >>> id(l)
    140359172142472
    >>> l = l + [1, 2, 3]
    >>> id(l)
    140359172167560


    In some cases, this can produce subtle bugs, because += mutates the original list, while
    l = l + iterable builds a new list and reassigns the name l.



    BONUS



    Ned Batchelder's challenge to find this in the docs






    share|improve this answer


















    • 1




      Thorough explanation. Thank you!
      – Luke Bakare
      29 mins ago














    up vote
    9
    down vote



    accepted










    They don't have to be the same.



    Using the + operator calls the method __add__ while using the += operator calls __iadd__. It is completey up to the object in question what happens when one of these methods is called.



    If you use x += y but x does not provide an __iadd__ method, __add__ is used as a fallback, e.g. x = x + y happens.



    In the case of lists, using l += iterable actually extends the list l with the elements of iterable. In your case, every character from the string (which is an iterable) is appended during the extend operation.



    Demo 1: using __iadd__



    >>> l = 
    >>> l += 'table'
    >>> l
    ['t', 'a', 'b', 'l', 'e']


    Demo 2: using extend does the same



    >>> l = 
    >>> l.extend('table')
    >>> l
    ['t', 'a', 'b', 'l', 'e']


    Demo 3: adding a list and a string raises a TypeError.



    >>> l = 
    >>> l = l + 'table'
    [...]
    TypeError: can only concatenate list (not "str") to list


    Not using += gives you the TypeError here because only __iadd__ implements the extending behavior.



    Demo 4: common pitfall: += does not build a new list (note the identical ids)



    >>> l = 
    >>> id(l)
    140359172117512
    >>> l += [1, 2, 3]
    >>> id(l)
    140359172117512


    ... but the l = l + iterable syntax does.



    >>> l = 
    >>> id(l)
    140359172142472
    >>> l = l + [1, 2, 3]
    >>> id(l)
    140359172167560


    In some cases, this can produce subtle bugs, because += mutates the original list, while
    l = l + iterable builds a new list and reassigns the name l.



    BONUS



    Ned Batchelder's challenge to find this in the docs






    share|improve this answer


















    • 1




      Thorough explanation. Thank you!
      – Luke Bakare
      29 mins ago












    up vote
    9
    down vote



    accepted







    up vote
    9
    down vote



    accepted






    They don't have to be the same.



    Using the + operator calls the method __add__ while using the += operator calls __iadd__. It is completey up to the object in question what happens when one of these methods is called.



    If you use x += y but x does not provide an __iadd__ method, __add__ is used as a fallback, e.g. x = x + y happens.



    In the case of lists, using l += iterable actually extends the list l with the elements of iterable. In your case, every character from the string (which is an iterable) is appended during the extend operation.



    Demo 1: using __iadd__



    >>> l = 
    >>> l += 'table'
    >>> l
    ['t', 'a', 'b', 'l', 'e']


    Demo 2: using extend does the same



    >>> l = 
    >>> l.extend('table')
    >>> l
    ['t', 'a', 'b', 'l', 'e']


    Demo 3: adding a list and a string raises a TypeError.



    >>> l = 
    >>> l = l + 'table'
    [...]
    TypeError: can only concatenate list (not "str") to list


    Not using += gives you the TypeError here because only __iadd__ implements the extending behavior.



    Demo 4: common pitfall: += does not build a new list (note the identical ids)



    >>> l = 
    >>> id(l)
    140359172117512
    >>> l += [1, 2, 3]
    >>> id(l)
    140359172117512


    ... but the l = l + iterable syntax does.



    >>> l = 
    >>> id(l)
    140359172142472
    >>> l = l + [1, 2, 3]
    >>> id(l)
    140359172167560


    In some cases, this can produce subtle bugs, because += mutates the original list, while
    l = l + iterable builds a new list and reassigns the name l.



    BONUS



    Ned Batchelder's challenge to find this in the docs






    share|improve this answer














    They don't have to be the same.



    Using the + operator calls the method __add__ while using the += operator calls __iadd__. It is completey up to the object in question what happens when one of these methods is called.



    If you use x += y but x does not provide an __iadd__ method, __add__ is used as a fallback, e.g. x = x + y happens.



    In the case of lists, using l += iterable actually extends the list l with the elements of iterable. In your case, every character from the string (which is an iterable) is appended during the extend operation.



    Demo 1: using __iadd__



    >>> l = 
    >>> l += 'table'
    >>> l
    ['t', 'a', 'b', 'l', 'e']


    Demo 2: using extend does the same



    >>> l = 
    >>> l.extend('table')
    >>> l
    ['t', 'a', 'b', 'l', 'e']


    Demo 3: adding a list and a string raises a TypeError.



    >>> l = 
    >>> l = l + 'table'
    [...]
    TypeError: can only concatenate list (not "str") to list


    Not using += gives you the TypeError here because only __iadd__ implements the extending behavior.



    Demo 4: common pitfall: += does not build a new list (note the identical ids)



    >>> l = 
    >>> id(l)
    140359172117512
    >>> l += [1, 2, 3]
    >>> id(l)
    140359172117512


    ... but the l = l + iterable syntax does.



    >>> l = 
    >>> id(l)
    140359172142472
    >>> l = l + [1, 2, 3]
    >>> id(l)
    140359172167560


    In some cases, this can produce subtle bugs, because += mutates the original list, while
    l = l + iterable builds a new list and reassigns the name l.



    BONUS



    Ned Batchelder's challenge to find this in the docs







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 14 mins ago

























    answered 39 mins ago









    timgeb

    38k104876




    38k104876







    • 1




      Thorough explanation. Thank you!
      – Luke Bakare
      29 mins ago












    • 1




      Thorough explanation. Thank you!
      – Luke Bakare
      29 mins ago







    1




    1




    Thorough explanation. Thank you!
    – Luke Bakare
    29 mins ago




    Thorough explanation. Thank you!
    – Luke Bakare
    29 mins ago












    up vote
    0
    down vote













    If in the second case you cast the n to a list to avoid errors:



    for n in l:
    i = i + [n]
    print(i)


    you get



    ['table']


    so they do different operations.






    share|improve this answer
























      up vote
      0
      down vote













      If in the second case you cast the n to a list to avoid errors:



      for n in l:
      i = i + [n]
      print(i)


      you get



      ['table']


      so they do different operations.






      share|improve this answer






















        up vote
        0
        down vote










        up vote
        0
        down vote









        If in the second case you cast the n to a list to avoid errors:



        for n in l:
        i = i + [n]
        print(i)


        you get



        ['table']


        so they do different operations.






        share|improve this answer












        If in the second case you cast the n to a list to avoid errors:



        for n in l:
        i = i + [n]
        print(i)


        you get



        ['table']


        so they do different operations.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 24 mins ago









        Jake

        278114




        278114




















            Luke Bakare is a new contributor. Be nice, and check out our Code of Conduct.









             

            draft saved


            draft discarded


















            Luke Bakare is a new contributor. Be nice, and check out our Code of Conduct.












            Luke Bakare is a new contributor. Be nice, and check out our Code of Conduct.











            Luke Bakare is a new contributor. Be nice, and check out our Code of Conduct.













             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52747784%2fis-i-i-n-truly-the-same-as-i-n%23new-answer', 'question_page');

            );

            Post as a guest













































































            Comments

            Popular posts from this blog

            Long meetings (6-7 hours a day): Being “babysat” by supervisor

            Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

            Confectionery