在原地更新列表

3

我有一个字符串列表,其中一些以换行符号结尾。我想通过从以此结尾的字符串中删除 \n 来修改此列表。为此,我使用以下代码:

aList = ['qwerttyy\n', '123454\n', 'zxcv']

for s in aList:
    if s.endswith('\n'):
    s = s[: -1]
        print(s)

输出结果如下:
    qwerttyy
    123454
    >>> aList
    ['qwerttyy\n', '123454\n', 'zxcv']
因此,原始列表未被更改,尽管列表是可变对象。为什么会出现这种情况?
4个回答

2
您可以使用切片赋值和列表推导式:
```python ```
>>> 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']

你的代码没有生效,因为它等价于:

s = aList[0]
if s.endswith('\n'):
    s = s[: -1]
s = aList[1]
if s.endswith('\n'):
    s = s[: -1]
...

即你正在更新变量 s,而不是实际的列表项。

1
因为for循环会复制字符串。
你可以使用: [s[:-1] if s.endswith('\n') else s for s in aList] 也许这更简单,不过它也会移除空格。 [s.strip() for s in aList]

1
这不会在原地修改列表。 - Paulo Bu
好的。然后重新赋值列表:aList = [s[:-1] if s.endswith('\n') else s for s in aList] - Nicolas Defranoux

0
尝试这个。
>>> aList = ['qwerttyy\n', '123454\n', 'zxcv']
>>> aList = [x[:-1] if x.endswith('\n') else x for x in aList]
>>> aList
['qwerttyy', '123454', 'zxcv']

不完全正确,你在列表的第三个元素里掉了一个 'v'。 - Jeff Langemeier

0

使用列表推导式str.rstrip

>>> aList = ['qwerttyy\n', '123454\n', 'zxcv']
>>> [s.rstrip('\n') for s in aList]
['qwerttyy', '123454', 'zxcv']

以上代码将创建一个新列表。要修改原始列表,请使用切片(list[:] = ...):

>>> aList
['qwerttyy\n', '123454\n', 'zxcv']
>>> aList[:] = [s.rstrip('\n') for s in aList]
>>> aList
['qwerttyy', '123454', 'zxcv']

注意:当有多个尾随换行符时,str.rstrip[:-1] 返回的结果不同:

>>> 'qwerttyy\n\n'.rstrip('\n')
'qwerttyy'
>>> 'qwerttyy\n\n'[:-1]
'qwerttyy\n'

请注意,当x为类似于“foo\n\n”的内容时,x[:-1]x.strip('\n')之间存在差异。 - Ashwini Chaudhary
@AshwiniChaudhary,感谢您的评论。我已经添加了一条注释。 - falsetru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接