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
8
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
    1 hour ago










  • "What is causing this strange error?" It's not an error. It's the behavior of an overloaded operator.
    – GreenMatt
    1 hour 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
    1 hour ago














up vote
8
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
    1 hour ago










  • "What is causing this strange error?" It's not an error. It's the behavior of an overloaded operator.
    – GreenMatt
    1 hour 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
    1 hour ago












up vote
8
down vote

favorite
2









up vote
8
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 operator-overloading






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 22 mins ago









Maximillian Laumeister

15.4k63155




15.4k63155






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 1 hour ago









Luke Bakare

433




433




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
    1 hour ago










  • "What is causing this strange error?" It's not an error. It's the behavior of an overloaded operator.
    – GreenMatt
    1 hour 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
    1 hour ago












  • 4




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










  • "What is causing this strange error?" It's not an error. It's the behavior of an overloaded operator.
    – GreenMatt
    1 hour 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
    1 hour ago







4




4




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




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












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




"What is causing this strange error?" It's not an error. It's the behavior of an overloaded operator.
– GreenMatt
1 hour 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
1 hour 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
1 hour ago












2 Answers
2






active

oldest

votes

















up vote
12
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
    54 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
    12
    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
      54 mins ago














    up vote
    12
    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
      54 mins ago












    up vote
    12
    down vote



    accepted







    up vote
    12
    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 39 mins ago

























    answered 1 hour ago









    timgeb

    38k104877




    38k104877







    • 1




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












    • 1




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







    1




    1




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




    Thorough explanation. Thank you!
    – Luke Bakare
    54 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 49 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













































































            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Displaying single band from multi-band raster using QGIS

            How many registers does an x86_64 CPU actually have?