It doesn’t work because
in has no binding to the elements.
i cannot be changed because this type of loop is Read Only and
i being the variable associated with
for is protected.
It is correct that a string cannot be changed, but we can create an expression from the string and save it as a new assignment to the same variable.
s = s + "s"
That’s because we simply gave
s a new reference, the value of the expression on the right side of the assignment.
There are moving pieces in a comprehension, just as in
list.append() for loop logic. Some find it easier to learn A before B, and others, B before A. For these iterators, it should be clear what
.append() does… It mutates an object. Comprehensions create objects. All the logic to create it is contained in the delimiters that Python recognizes, whether list, tuple, set, dict, etc.
[expression_to_append for element in iterable]
The value we append can be the element modified by any valid expression.
We cannot access the object we are creating which means we cannot check for duplicates. If duplicates are an issue, build a set comprehension which can then be cast to a tuple or list or dict.
In your program task you have an array where each element is a string. It’s because it is a
str object that we have a
strip() method. It is an attribute of the the
str class, and inherited by all objects of the type.
The process is meant to reduce all the strings to be free of white space either leading or trailing. That is why we can do this,
stripped_lines = [line.strip() for line in lines]
Now to see that in a loop,
stripped_lines = 
for line in lines:
Note that we are not attempting to change
line, only use it in the construction of a new value, which is the object we create in the expression.