为什么在 split()结果中返回空字符串?

返回 ['', 'segment', 'segment', '']的意义是什么?

注意空元素。如果分隔符恰好位于字符串的第一个位置和最后一个位置,那么从每个位置返回空字符串会给你多少额外值呢?

99447 次浏览

我不知道你想要什么答案?你得到三个匹配,因为你有三个分隔符。如果你不想要那个空的,就用:

'/segment/segment/'.strip('/').split('/')

str.split 补充 str.join,因此

"/".join(['', 'segment', 'segment', ''])

返回原始字符串。

如果不存在空字符串,则在 join()之后将缺少第一个和最后一个 '/'

它让你知道那里有一个分界线。所以,看到4个结果让你知道你有3个分隔符。这使您能够对这些信息做任何您想做的事情,而不是让 Python 删除空元素,然后让您手动检查开始或结束分隔符,如果您需要知道它。

简单的例子: 假设您想检查绝对文件名和相对文件名。通过这种方式,您可以使用分割来完成所有操作,而不必检查文件名的第一个字符是什么。

这里有两个要点需要考虑:

  • 期望 '/segment/segment/'.split('/')的结果等于 ['segment', 'segment']是合理的,但这样就会丢失信息。如果 split()按照你想要的方式工作,如果我告诉你 a.split('/') == ['segment', 'segment'],你不能告诉我 a是什么。
  • 'a//b'.split()的结果应该是什么?['a', 'b']?还是 ['a', '', 'b']?也就是说,split()应该合并相邻的分隔符吗?如果应该,那么解析由字符分隔的数据将非常困难,而且有些字段可能是空的。我相当肯定有很多人谁 想要的结果中的空值为上述情况!

最后,归结为两件事:

一致性: 如果我有 n分隔符,在 a中,我会在 split()之后得到 n+1值。

做复杂的事情应该是可能的,做简单的事情应该是容易的: 如果你想忽略由于 split()而产生的空字符串,你总是可以做:

def mysplit(s, delim=None):
return [x for x in s.split(delim) if x]

但是如果不想忽略空值,那么 应该可以。

该语言必须选择一个 split()的定义; 有太多不同的用例来满足每个人的默认需求。我认为 Python 的选择是一个很好的选择,也是最符合逻辑的。(顺便说一句,我不喜欢 C 的 strtok()的原因之一是它合并了相邻的分隔符,这使得对它进行严肃的解析/标记化变得极其困难。)

有一个例外: 没有参数的 a.split()会挤压连续的空白,但是在这种情况下,可以认为这样做是正确的。如果你不想要的行为,你可以随时到 a.split(' ')

x.split(y)总是返回一个 1 + x.count(y)条目的列表是一个宝贵的规律——正如@nibbler 已经指出的那样,它使得 splitjoin彼此完全相反(显然它们应该是相反的) ,它还精确地映射了所有类型的分隔符连接的记录的语义(比如 csv文件行[[净引用问题]] ,Unix 中 /etc/group的行,等等) ,它允许(如@Roman 的回答所提到的)简单地检查(例如)绝对路径和相对路径(在文件路径和 URL 中) ,等等。

另一种看待它的方式是,你不应该毫无收获地把信息随意扔出窗外。使 x.split(y)等效于 x.strip(y).split(y)能获得什么?当然,没什么——当你指的是第二种形式时,使用第二种形式很容易,但是如果第一种形式被任意地认为是指第二种形式,那么当你想要 的第一种形式时,你就有很多工作要做(正如前一段所指出的,这种情况并不罕见)。

但实际上,从数学规律的角度思考是您可以自学设计合格 API 的最简单和最一般的方法。举一个不同的例子,对于任何有效的 xy x == x[:y] + x[y:]都非常重要——这立即表明为什么要排除切片 应该的一个极端。你能够形成的不变式断言越简单,得到的语义就越有可能是你在现实生活中所需要的——这是一个神秘的事实: 数学在处理宇宙问题时非常有用。

反例: 字符串方法,例如 isspace并不是最简单的—— x.isspace()等同于 x and all(c in string.whitespace for c in x)——愚蠢的字符串方法就是为什么你经常发现自己编码 not x or x.isspace()的原因,回到 应该被设计成 is...字符串方法的那种简单性(空字符串“是”你想要的任何东西——这与街上的人的马的感觉相反,也许[[空集,像零 & c,总是让大多数人困惑; ——]] ,但是完全符合显而易见的精炼的 数学常识!-).

更一般地说,要删除在 split()结果中返回的空字符串,您可能需要查看 filter函数。

例如:

f = filter(None, '/segment/segment/'.split('/'))
s_all = list(f)

报税表

['segment', 'segment']

考虑一下这个最小的例子:

>>> '/'.split('/')
['', '']

split必须给出分隔符 '/'之前和之后的内容,但是没有其他字符。因此,已经给出空字符串,它在技术上位于 '/'之前和之后,因为 '' + '/' + '' == '/'

如果您不希望 split返回空格,请使用没有参数的空格。

>>> "  this   is  a sentence ".split()
['this', 'is', 'a', 'sentence']
>>> "  this   is  a sentence ".split(" ")
['', '', 'this', '', '', 'is', '', 'a', 'sentence', '']