4

I want to make sense of difference between list +='a' and list=list+'a' For example, if I do this:

li=[]
for i in 'string':
    li+=i

I get no error but if I use the second option which by convention should be the same but gives error

li=[]
for i in 'string':
    li=li+i

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

Correct way to do this, would be something like this:

li=[]
for i in 'string':
    li=li+[i]

I want to know how += operator is working? How it is able to get string inside the list, is it converting string to list?

M_S_N
  • 2,764
  • 1
  • 17
  • 38
  • 2
    The return type of `+=` is unambiguous: it's the type of the left operand. The return type of `+` is unclear. Does the programmer expect `list + str` to return a list, or a string? – khelwood Mar 11 '20 at 10:00
  • 2
    [Why does += behave unexpectedly on lists?](https://stackoverflow.com/questions/2347265/why-does-behave-unexpectedly-on-lists) – Sayse Mar 11 '20 at 10:02
  • @khelwood `list` should be returned – M_S_N Mar 11 '20 at 10:04
  • `+=` is equivalent to `list.extend` which accepts any iterable (not only lists) – hurlenko Mar 11 '20 at 10:05
  • Anyways, you can use `li+=[i]`. – shaik moeed Mar 11 '20 at 10:07
  • 1
    Does this answer your question? [Why does += behave unexpectedly on lists?](https://stackoverflow.com/questions/2347265/why-does-behave-unexpectedly-on-lists) – Meha Parekh Mar 11 '20 at 10:07
  • @M_S_N Yeah, I understand that's what *you* want in this use case. That doesn't hold for every developer in every possible use case. – khelwood Mar 11 '20 at 10:09

2 Answers2

2

I want to know how += operator is working?

the in-place assignment += operator works in 2 ways (from the docs):

1)For immutable objects

For immutable targets such as strings, numbers, and tuples, the updated value is computed, but not assigned back to the input variable

this means that you will create a new object each time += is used (if your object is immutable)

2)For mutable objects

For mutable targets such as lists and dictionaries, the in-place method will perform the update, so no subsequent assignment is necessary

this means that you will not create a new object each time += is used (if your object is mutable)


In your example, to use li+=i you have to make sure that i is a list, otherwise will not work

Here:

li = []
for i in 'string':
    li = li + [i]

you are concatenating 2 lists but each time you are creating a new list li, you can check by using the built-in funtion id:

li=[]
for i in '1':
    print(id(li))
    li=li+[i]
    print(id(li))

output:

140661631713104
140661644452240

you could use the in-place assignment += operator like this:

li=[]
for i in '1':
    print(id(li))
    li += [i]
    print(id(li))

output:

140661641698592
140661641698592

as you can see the elements are appended to the li list without creating a new li list which is more efficient, this works identically like list.extend

to add another element to your list, not using a list, you can use list.append

M_S_N
  • 2,764
  • 1
  • 17
  • 38
kederrac
  • 16,819
  • 6
  • 32
  • 55
  • your answer makes a lot sense, but still a very strange design choice, especially coming from another language where something like this `a+=a` would be equivalent to `a= a+a` – M_S_N Mar 12 '20 at 04:54
1

Python docs says:

To see why this happens, you need to know that (a) if an object implements an __iadd__ magic method, it gets called when the += augmented assignment is executed, and its return value is what gets used in the assignment statement; and (b) for lists, __iadd__ is equivalent to calling extend on the list and returning the list. That’s why we say that for lists, += is a “shorthand” for list.extend.

Since list.extend expects an iterator and a string is iterable, += works in your given example. That means, you don't even need the for-loop as list.extend will iterate through the string and add the elements to the list.
li=[] li += "string" Output: ['s', 't', 'r', 'i', 'n', 'g']

List can only concatenate (+) list.

Source:
https://docs.python.org/3/tutorial/datastructures.html https://docs.python.org/3/reference/datamodel.html#emulating-numeric-types https://docs.python.org/3/faq/programming.html#faq-augmented-assignment-tuple-error

Cihat
  • 835
  • 1
  • 7
  • 17