Reputation: 136
I have a list of strings, some of them ends with new line symbol. I want to modify this list by removing \n from strings which ends with it. For this purpose I use the following code:
aList = ['qwerttyy\n', '123454\n', 'zxcv']
for s in aList:
if s.endswith('\n'):
s = s[: -1]
print(s)
The output is the following:
qwerttyy 123454 >>> aList ['qwerttyy\n', '123454\n', 'zxcv']
So the original list wasn't changed though list is mutable object. What is the reason of such behavior?
Upvotes: 3
Views: 123
Reputation: 21253
try this
>>> aList = ['qwerttyy\n', '123454\n', 'zxcv']
>>> aList = [x[:-1] if x.endswith('\n') else x for x in aList]
>>> aList
['qwerttyy', '123454', 'zxcv']
Upvotes: 0
Reputation: 369134
Using list comprehension and str.rstrip
>>> aList = ['qwerttyy\n', '123454\n', 'zxcv']
>>> [s.rstrip('\n') for s in aList]
['qwerttyy', '123454', 'zxcv']
Above will create new list. To modify the original list, use slicing (list[:] = ...
):
>>> aList
['qwerttyy\n', '123454\n', 'zxcv']
>>> aList[:] = [s.rstrip('\n') for s in aList]
>>> aList
['qwerttyy', '123454', 'zxcv']
NOTE str.rstrip
returns different result from [:-1]
when tehre are multiple trailing newlines:
>>> 'qwerttyy\n\n'.rstrip('\n')
'qwerttyy'
>>> 'qwerttyy\n\n'[:-1]
'qwerttyy\n'
Upvotes: 0
Reputation: 250991
You can use slice assignment and a list comprehension:
>>> foo = aList = ['qwerttyy\n', '123454\n', 'zxcv']
>>> aList[:] = [s[:-1] if s.endswith('\n') else s for s in aList]
>>> foo #All references are affected.
['qwerttyy', '123454', 'zxcv']
>>> aList
['qwerttyy', '123454', 'zxcv']
Your code didn't work because it is equivalent to:
s = aList[0]
if s.endswith('\n'):
s = s[: -1]
s = aList[1]
if s.endswith('\n'):
s = s[: -1]
...
i.e You're updating the variable s
, not the actual list item
Upvotes: 2
Reputation: 2676
because the for loop makes copies of strings.
You can use:
[s[:-1] if s.endswith('\n') else s for s in aList]
Maybe this is simpler, though it will remove also whitespaces.
[s.strip() for s in aList]
Upvotes: 1