Answers:
问题:我正在使用split('\ n')在一个字符串中获取行,并发现''.split()返回空列表[],而''.split('\ n')返回[''] 。
所述str.split()方法有两种算法。如果未提供任何参数,它将在重复运行空白时拆分。但是,如果给出参数,则将其视为单个定界符,且不会重复运行。
在拆分空字符串的情况下,第一种模式(无参数)将返回一个空列表,因为空白被吃掉并且结果列表中没有任何值。
相比之下,第二种模式(带有参数如\n
)将产生第一个空字段。考虑一下您是否写过'\n'.split('\n')
,您将得到两个字段(一个字段拆分成两半)。
问题:有什么特殊原因造成这种差异?
当数据在具有可变空白量的列中对齐时,第一种模式很有用。例如:
>>> data = '''\
Shasta California 14,200
McKinley Alaska 20,300
Fuji Japan 12,400
'''
>>> for line in data.splitlines():
print line.split()
['Shasta', 'California', '14,200']
['McKinley', 'Alaska', '20,300']
['Fuji', 'Japan', '12,400']
第二种模式对于定界数据(例如CSV)很有用,其中重复的逗号表示空白字段。例如:
>>> data = '''\
Guido,BDFL,,Amsterdam
Barry,FLUFL,,USA
Tim,,,USA
'''
>>> for line in data.splitlines():
print line.split(',')
['Guido', 'BDFL', '', 'Amsterdam']
['Barry', 'FLUFL', '', 'USA']
['Tim', '', '', 'USA']
注意,结果字段的数量比定界符的数量大一。想想剪一条绳子。如果不削减,则只有一件。一切,给出两块。进行两次切割,得到三块。Python的str.split(delimiter)方法也是如此:
>>> ''.split(',') # No cuts
['']
>>> ','.split(',') # One cut
['', '']
>>> ',,'.split(',') # Two cuts
['', '', '']
问题:还有什么更方便的方法来计算字符串中的行数?
是的,有两种简单的方法。一个使用str.count(),另一个使用str.splitlines()。除非最后一行缺少,否则两种方法都将给出相同的答案\n
。如果最后的换行符丢失,则str.splitlines方法将给出准确的答案。一种更快且更准确的技术是使用count方法,然后将其更正为最终的换行符:
>>> data = '''\
Line 1
Line 2
Line 3
Line 4'''
>>> data.count('\n') # Inaccurate
3
>>> len(data.splitlines()) # Accurate, but slow
4
>>> data.count('\n') + (not data.endswith('\n')) # Accurate and fast
4
来自@Kaz的问题:为什么两个非常不同的算法被误用到一个函数中?
str.split的签名大约有20年的历史了,那个时代的许多API都是严格实用的。虽然并不完美,但方法签名也不是“糟糕的”。在大多数情况下,Guido的API设计选择经受了时间的考验。
当前的API并非没有优势。考虑如下字符串:
ps_aux_header = "USER PID %CPU %MEM VSZ"
patient_header = "name,age,height,weight"
当要求将这些字符串分成多个字段时,人们倾向于使用相同的英语单词“ split”来描述这两个字符串。当要求读取诸如fields = line.split()
或的代码时fields = line.split(',')
,人们倾向于正确地将语句解释为“将行拆分为字段”。
Microsoft Excel的“ 文本到列”工具做出了类似的API选择,并将两种分割算法都合并到了同一工具中。尽管似乎涉及多个算法,但人们似乎在思维上将字段拆分建模为一个单独的概念。
用途count()
:
s = "Line 1\nLine2\nLine3"
n_lines = s.count('\n') + 1
cat file
会使您的命令行乱码,颠覆抱怨。vi总是附加一个。
>>> print str.split.__doc__
S.split([sep [,maxsplit]]) -> list of strings
Return a list of the words in the string S, using sep as the
delimiter string. If maxsplit is given, at most maxsplit
splits are done. If sep is not specified or is None, any
whitespace string is a separator and empty strings are removed
from the result.
注意最后一句话。
要计算行数,您可以简单地计算行数\n
:
line_count = some_string.count('\n') + some_string[-1] != '\n'
最后一部分考虑到不结束最后一行\n
,即使这意味着,Hello, World!
与Hello, World!\n
具有相同的行数(这对我来说是合理的),否则,你可以简单地添加1
到的计数\n
。