Aleks Lee
Aleks Lee

Reputation: 136

Updating list in-place

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

Answers (4)

Neel
Neel

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

falsetru
falsetru

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

Ashwini Chaudhary
Ashwini Chaudhary

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

Nicolas Defranoux
Nicolas Defranoux

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

Related Questions