如何从列表元素中删除\ n?


77

我正在尝试使Python到达.txt文件的读取行,并将第一行的元素写入列表。该文件中的元素是制表符分隔的,因此我过去常常split("\t")将这些元素分隔开。由于.txt文件包含很多元素,因此我将每一行中找到的数据保存到单独的列表中。

我目前遇到的问题是,它正在显示每个列表,如下所示:

['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']

如何\n从列表的最后一个元素中删除并使其正确'7.3'


对于您拥有的数据,只需使用split()(无参数)。它将首先剥离空白,然后在空白上拆分。
JoshD

Answers:


144

如果只想\n从最后一个元素中删除,请使用以下命令:

t[-1] = t[-1].strip()

如果\n要从所有元素中删除,请使用以下命令:

t = map(lambda s: s.strip(), t)

您还可以考虑\n 拆分行之前将其删除:

line = line.strip()
# split line...

5
我会在拆分之前先做个剥离...我觉得它更简洁。
st0le 2010年

2
晕!有用!非常感谢你。
Wotan先生,2010年

8
如果我要遍历列表,我也会使用[s.strip() for s in t]。我为它计时,处理["s\n"]*10000时间为5.33毫秒,而处理时间为9.73毫秒mapmap如果映射的是内置对象,则将获胜。
aaronasterling

3
line = line.strip()将删除所有的追踪白空间。这是屠杀。阅读Jim Dennis的答案。
John Machin 2010年

1
@约翰·真。不仅如此,它还将删除所有前导空格。在许多情况下,它line.strip()会比line.rstrip('\n')这更合理,这就是为什么我在没有进一步解释的情况下编写它的原因。但是,在这种情况下(制表符分隔的值),您100%正确:删除前导和尾随空格时应格外小心,因为空的第一列或最后一列可能会“消失”。
Bolo 2010年

48

从Python3开始

map不再返回alist而是a mapObject,因此答案将类似于

>>> map(lambda x:x.strip(),l)
<map object at 0x7f00b1839fd0>

您可以在Python 3.0新增功能中阅读更多有关它的内容。

map()filter()返回迭代器。如果您确实需要一个list,快速修复例如list(map(...))

那么,现在有什么方法可以解决这个问题呢?


案例1 -将list在通话maplambda

map返回一个迭代器list是可以将迭代器转换为列表的函数。因此,您将需要包装一个list呼叫map。所以答案就变成了

>>> l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
>>> list(map(lambda x:x.strip(),l))
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

很好,我们得到了输出。现在,我们检查这段代码执行所花费的时间。

$ python3 -m timeit "l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'];list(map(lambda x:x.strip(),l))"
100000 loops, best of 3: 2.22 usec per loop

2.22微秒。那还不错。但是还有更有效的方法吗?


情况2-list呼叫maplambda

lambda在Python社区(包括Guido)中,很多人对此并不满意。除此之外,它将大大降低程序的速度。因此,我们需要尽可能避免这种情况。顶级功能str.strip。在这里为我们提供帮助。

map可以不使用重新编写lambda使用str.strip作为

>>> list(map(str.strip,l))
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

现在是时代。

$ python3 -m timeit "l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'];list(map(str.strip,l))"
1000000 loops, best of 3: 1.38 usec per loop

太棒了 您会看到两种方法之间的效率差异。它快了近60%。因此,lambda此处不使用a的方法是更好的选择。


案例3-遵循准则,常规方法

Python 3.0新增功能的另一个重要点是,它建议我们尽可能避免map使用。

map()该函数的副作用特别棘手。正确的转换是使用常规for循环(因为创建列表只是浪费)。

因此,我们可以map通过使用常规for循环来解决此问题而无需使用。

解决(蛮力)的简单方法是:

>>> l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
>>> final_list = []
>>> for i in l:
...     final_list.append(i.strip())
... 
>>> final_list
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

计时设置

def f():
    l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
    final_list = []
    for i in l:
         final_list.append(i.strip())
import timeit
print(min(timeit.repeat("f()","from __main__ import f")))

结果。

1.5322505849981098

如您所见,这里的蛮力要慢一些。但是对于普通程序员而言,绝对比map子句更具可读性。


情况4-清单推导

这里的列表理解也是可能的,并且与Python2中的相同。

>>> [i.strip() for i in l]
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

现在是时候了:

$ python3 -m timeit "l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'];[i.strip() for i in l]"
1000000 loops, best of 3: 1.28 usec per loop

如您所见,列表理解比map(甚至没有lambda)更有效。因此,Python3中的经验法则是使用列表理解而不是map


案例5-就地机制和空间效率(TMT

最后一种方法是在列表本身内进行更改。这样可以节省大量的存储空间。可以使用来完成enumerate

>>> l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
>>> for i,s in enumerate(l):
...     l[i] = s.strip()
... 
>>> l
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

计时结果将为1.4806894720022683。但是,这种方式节省空间。


结论

定时比较列表(Python 3.4.3和Python 3.5.0)

----------------------------------------------------
|Case| method          | Py3.4 |Place| Py3.5 |Place|
|----|-----------------|-------|-----|-------|-----|
| 1  | map with lambda | 2.22u | 5   | 2.85u | 5   |
| 2  | map w/o lambda  | 1.38u | 2   | 2.00u | 2   |
| 3  | brute-force     | 1.53u | 4   | 2.22u | 4   |
| 4  | list comp       | 1.28u | 1   | 1.25u | 1   |
| 5  | in-place        | 1.48u | 3   | 2.14u | 3   |
----------------------------------------------------

最后请注意,列表理解是最好的方法,而map使用lambda是最差的方法。但再次---仅在PYTHON3中


11

听起来您想要类似Perlchomp()函数的东西。

这在Python中很简单:

def chomp(s):
    return s[:-1] if s.endswith('\n') else s

...假设您使用的是Python 2.6或更高版本。否则,请使用稍微冗长一些的内容:

def chomp(s):
    if s.endwith('\n'):
        return s[:-1]
    else:
        return s

如果您要删除字符串末尾的所有新行(在奇怪的情况下,由于某些原因,其中可能会有多个尾随新行):

def chomps(s):
    return s.rstrip('\n')

显然,您永远都不会看到任何普通的Python文件对象的readline()norreadlines()方法返回的字符串。

我见过人们盲目地s[:-1]从文件readline()和类似函数的结果中删除最后一个字符(使用切片)。这是一个坏主意,因为它可能导致文件的最后一行出现错误(如果文件以换行符结尾,那么该错误)。

起初,当您盲目地将最后的字符从阅读的行中剥离时,您可能会陷入一种错误的安全感。如果您使用普通的文本编辑器创建测试套件文件,那么大多数文件将在最后一行的末尾静默添加换行符。要创建有效的测试文件,请使用类似以下的代码:

f = open('sometest.txt', 'w')
f.write('some text')
f.close()

...,然后,如果您重新打开该文件并使用readline()readlines()文件方法,您会发现读取的文本没有尾随换行符。

多年来,这种无法解释以非换行符结尾的文本文件的失败困扰了许多UNIX实用程序和脚本语言。这是一个愚蠢的死角基础错误,经常渗入代码中成为有害生物,但又不足以使人们从中学习。我们可以说没有最终换行符的“文本”文件是“损坏的”或非标准的;这可能对某些编程规范有效。

但是,很容易在我们的编码中忽略极端情况,而让无知之人咬人,这些人以后会依赖您的代码。正如我妻子所说:在编程时,请练习安全的十六进制!


1
+1在读取Python文本文件时,line = line.rstrip('\n')应在将行解析为字段之前,作为一个单独的步骤来检查是否存在换行符(或通过盲目删除它)。
约翰·马钦

6

使用列表理解:

myList = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']

[(el.strip()) for el in myList]

假设这样做的目的是剥离所有前导和尾随空白。这不是“删除尾随新行”的精确匹配。
吉姆·丹尼斯

3

从这个链接

您可以使用rstrip()方法。例

mystring = "hello\n"    
print(mystring.rstrip('\n'))

2

作为一种替代方法,如果您知道数据中没有空格(看起来确实是这种情况),则可以使用split()(不带参数)。它在空白处进行分割,并且使用比其他版本的分割更有效的算法。它还从两端剥离空格。

line = line.split()

就是这样。


2

你可以做-

DELIMITER = '\t'
lines = list()
for line in open('file.txt'):
    lines.append(line.strip().split(DELIMITER))

lines已经得到了你的文件的所有内容。

人们还可以使用列表推导来使其更紧凑。

lines = [ line.strip().split(DELIMITER) for line in open('file.txt')]

我正在使用这种方法的变体将文件转换为单行javascript变量。很好 感谢Srikar
扎克-

2

这也可以,

f=open('in.txt','r')

    for line in f:
            parline = line[:-1].split(',')

2

str.strip()删除空格字符。您还可以将自定义字符作为参数传递给strip。所述函数删除在串的两端的空白/自定义字符。lstrip()和rstrip()分别是左功能区和右功能区。

例如:

test_str = "Vishaka\n" 
test_str = test_str.strip()

test_str现在是Vishaka


1

您访问集合的最后一个元素,然后将值存储在变量中。

所以你有了:

fileName = '7.3\n'

然后做:

fileName.strip()

这将使您离开7.3。然后将该值存储在集合的最后一个元素中。

您可以使用lstrip()rstrip()删除左侧或右侧。


1

由于OP的问题是关于从最后一个元素中删除换行符,所以我将其重置为the_list[-1].rstrip()

>>> the_list = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
>>> the_list[-1] = ls[-1].rstrip()
>>> the_list
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

是O(1)。


0

这可以从\n列表中的项目中取出(新行)它只是将字符串中的第一个项目取出

def remove_end(s):
    templist=[]
    for i in s:
        templist.append(i)
    return(templist[0])

0

我遇到了这个问题,并使用上述的chomp函数解决了该问题:

def chomp(s):
    return s[:-1] if s.endswith('\n') else s

def trim_newlines(slist):
    for i in range(len(slist)):
        slist[i] = chomp(slist[i])
    return slist
.....
names = theFile.readlines()
names = trim_newlines(names)
....

1
这似乎只是先前答案的重复。如果添加了某些内容,请弄清楚是什么。
blm

0

要处理许多换行符定界符,包括类似的字符组合\r\n,请使用splitlines。合并连接线分割线以从字符串中删除/替换所有换行符s

''.join(s.splitlines())

完全删除一个尾随的换行符,请True作为keepends参数传递以保留定界符,仅删除最后一行的定界符:

def chomp(s):
    if len(s):
        lines = s.splitlines(True)
        last = lines.pop()
        return ''.join(lines + last.splitlines())
    else:
        return ''

0
new_list = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
for i in range(len(new_list)):
    new_list[i]=new_list[i].replace('\n','')
print(new_list)

输出将像这样

['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.