我正在尝试使Python到达.txt文件的读取行,并将第一行的元素写入列表。该文件中的元素是制表符分隔的,因此我过去常常split("\t")
将这些元素分隔开。由于.txt文件包含很多元素,因此我将每一行中找到的数据保存到单独的列表中。
我目前遇到的问题是,它正在显示每个列表,如下所示:
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
如何\n
从列表的最后一个元素中删除并使其正确'7.3'
?
我正在尝试使Python到达.txt文件的读取行,并将第一行的元素写入列表。该文件中的元素是制表符分隔的,因此我过去常常split("\t")
将这些元素分隔开。由于.txt文件包含很多元素,因此我将每一行中找到的数据保存到单独的列表中。
我目前遇到的问题是,它正在显示每个列表,如下所示:
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
如何\n
从列表的最后一个元素中删除并使其正确'7.3'
?
Answers:
如果只想\n
从最后一个元素中删除,请使用以下命令:
t[-1] = t[-1].strip()
如果\n
要从所有元素中删除,请使用以下命令:
t = map(lambda s: s.strip(), t)
您还可以考虑\n
在拆分行之前将其删除:
line = line.strip()
# split line...
[s.strip() for s in t]
。我为它计时,处理["s\n"]*10000
时间为5.33毫秒,而处理时间为9.73毫秒map
。map
如果映射的是内置对象,则将获胜。
line = line.strip()
将删除所有的追踪白空间。这是屠杀。阅读Jim Dennis的答案。
line.strip()
会比line.rstrip('\n')
这更合理,这就是为什么我在没有进一步解释的情况下编写它的原因。但是,在这种情况下(制表符分隔的值),您100%正确:删除前导和尾随空格时应格外小心,因为空的第一列或最后一列可能会“消失”。
map
不再返回alist
而是a mapObject
,因此答案将类似于
>>> map(lambda x:x.strip(),l)
<map object at 0x7f00b1839fd0>
您可以在Python 3.0新增功能中阅读更多有关它的内容。
map()
并filter()
返回迭代器。如果您确实需要一个list
,快速修复例如list(map(...))
那么,现在有什么方法可以解决这个问题呢?
list
在通话map
用lambda
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微秒。那还不错。但是还有更有效的方法吗?
list
呼叫map
无lambda
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的方法是更好的选择。
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
子句更具可读性。
这里的列表理解也是可能的,并且与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
最后一种方法是在列表本身内进行更改。这样可以节省大量的存储空间。可以使用来完成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中
听起来您想要类似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实用程序和脚本语言。这是一个愚蠢的死角基础错误,经常渗入代码中成为有害生物,但又不足以使人们从中学习。我们可以说没有最终换行符的“文本”文件是“损坏的”或非标准的;这可能对某些编程规范有效。
但是,很容易在我们的编码中忽略极端情况,而让无知之人咬人,这些人以后会依赖您的代码。正如我妻子所说:在编程时,请练习安全的十六进制!
line = line.rstrip('\n')
应在将行解析为字段之前,作为一个单独的步骤来检查是否存在换行符(或通过盲目删除它)。
你可以做-
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')]
str.strip()删除空格字符。您还可以将自定义字符作为参数传递给strip。所述条函数删除在串的两端的空白/自定义字符。lstrip()和rstrip()分别是左功能区和右功能区。
例如:
test_str = "Vishaka\n"
test_str = test_str.strip()
test_str现在是Vishaka
我遇到了这个问题,并使用上述的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)
....
要处理许多换行符定界符,包括类似的字符组合\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 ''
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']