-1

I have these lines of code and I don't understand why does it work.

list_ = []
string = '12345'
for i in string:
    list_ += i
print(list_)
#Output: ['1', '2', '3', '4', '5']

People say this is the magic of python and I have this link below, but I do not have sufficient background in C https://github.com/python/cpython/blob/998ae1fa3fb05a790071217cf8f6ae3a928da13f/Objects/listobject.c#L977

Edit: The question is why this does not rise an exception? string is not a list, it is an iterable

first_list = [] + 'a'
print(first_list)

#TypeError: can only concatenate list (not "str") to list
Benku BBB
  • 1
  • 3
  • 1
    Why *wouldn't* it work? In what way were you expecting this to fail? – jasonharper Jan 18 '21 at 06:06
  • Are you confused by the `for i in string:` part? A string variable, like many types in Python is an iterable, which means you can iterate over its parts. Other examples are tuples, lists, but also specialised types like the pair in a dict when using `.items()`. – Grismar Jan 18 '21 at 06:11
  • Please repeat [on topic](https://stackoverflow.com/help/on-topic) and [how to ask](https://stackoverflow.com/help/how-to-ask) from the [intro tour](https://stackoverflow.com/tour). "Explain this block of code to me" is off-topic for Stack Overflow. *Specifically* what do you not understand? Trace the values like you're supposed to, and describe just what confuses you. This is straightforward iteration and concatenation; Stack Overflow is not intended to replace existing tutorials and documentation. – Prune Jan 18 '21 at 06:12
  • `str` is a [text sequence type](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str). – Klaus D. Jan 18 '21 at 06:19
  • Because `+=` is documented as being equivalent to `.extend`, and `.extend` accepts any iterable – juanpa.arrivillaga Jan 18 '21 at 07:12

2 Answers2

0

I assume you understand this part:

for i in string:

Therefore I will focus on this:

list_ += i

It works because in python there is no chartype. In python a single character is still a string. And a string is "iterable". And a list can be "extended" by an iterable.

list += another_list

means

list.extend(another_list)

E.g. this will not work:

list += 1

since 1 is just a single number, while

list += 'a'

will work fine because 'a' is not a character but a string which in turn is an iterable.

There are better explanations of this here and here.

fukanchik
  • 2,811
  • 24
  • 29
-1

A string is an iterable because the str class/type implements the __iter__ method. By implementing the __iter__ method, the for-loop is able to iterate all members in the string. Whenever the for-loop asks for the next element in the string, Python's str class's iterable returns it's string instance's next character. As a result, i, in the context of the for-loop, is always the next character in the string.

Within the loop, list_ += i class works because Python's list class/type implements the __iadd__ method. __iadd__ is a method that is called whenever Python encounters the += operator. Normally, the __iadd__ operation of list is used to add elements from one iterable to the end of a list instance. Because the method is meant to combine iterables, you would receive a TypeError: 'int' object is not iterable if your code was the following:

list_ = []
string = '12345'
for i in string:
    list_ += int(i)
print(list_)

However, your code works because, going back to the first discussion point, in Python, strings are iterables. As a result, it is perfectly legal in Python to say:

l=[]
s='omg'
l+=s
print(l)
# Output: ['o', 'm', 'g']

You might think your case is different than my example above because your case is looping over each character in the string rather than working with the string itself. However, Python does not have a character type, so effectively, every character (i) is a single-character string. As a result, every individual character i in your for-loop has its own __iter__ method, effectively allowing the character to be appended to the end of list_, as if the operation said: list += [i].

Spencer D
  • 3,376
  • 2
  • 27
  • 43
  • first_list = [] + 'a' print(first_list) #TypeError: can only concatenate list (not "str") to list; Question:why this block of code raise an exception. When we want to add manually – Benku BBB Jan 18 '21 at 06:54
  • You are missing the crucial point, this *doesn't* work because of `__add__` but because of `__iadd__` When using just `some_list + some_iterable` then `__add__` *will* throw a TypeError, because it only accepts lists. – juanpa.arrivillaga Jan 18 '21 at 07:13