问题:我正在使用split('\n')
获取一个字符串中的行,并发现''.split()
返回一个空列表,[]
, while ''.split('\n')
回报['']
.
The 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']
请注意,结果字段的数量比分隔符的数量大 1。想象一下割断一根绳子。如果你不做任何切割,你就得到了一件。切一刀,得到两块。进行两次切割,得到三块。 Python 也是如此str.split(delimiter)
method:
>>> ''.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()
or fields = line.split(',')
,人们倾向于将这些陈述正确地解释为“将一条线分割成多个字段”。
微软Excel的文本转列工具做出了类似的 API 选择并且
将两种分割算法合并在同一个工具中。尽管涉及不止一种算法,人们似乎在心理上将场分割建模为一个概念。