有没有关于str.split()拆分顺序的保证?

时间:2016-07-01 15:22:20

标签: python string python-2.7 split

根据the Python 2.7 docs,使用str.split()并指定maxsplit会将字符串拆分为maxsplit次。

但是,它从未明确指定这些拆分将从左到右执行。有一个相关的函数str.rsplit(),保证从右到左分裂排序。

除了执行字符串反转后跟str.rsplit(),还有什么方法可以保证从左到右的分割顺序?是否存在str.split()不会使用从左到右的顺序的情况?

2 个答案:

答案 0 :(得分:4)

如果您正在寻找通过maxsplit参数从左到右分割的保证,您只需要查看内置python test suite

这是一段摘录:

    self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'split', '|')
    self.checkequal(['a|b|c|d'], 'a|b|c|d', 'split', '|', 0)
    self.checkequal(['a', 'b|c|d'], 'a|b|c|d', 'split', '|', 1)
    self.checkequal(['a', 'b', 'c|d'], 'a|b|c|d', 'split', '|', 2)
    self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'split', '|', 3)
    self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'split', '|', 4)
    self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'split', '|',
                    sys.maxsize-2)
    self.checkequal(['a|b|c|d'], 'a|b|c|d', 'split', '|', 0)
    self.checkequal(['a', '', 'b||c||d'], 'a||b||c||d', 'split', '|', 2)
    self.checkequal(['abcd'], 'abcd', 'split', '|')
    self.checkequal([''], '', 'split', '|')
    self.checkequal(['endcase ', ''], 'endcase |', 'split', '|')
    self.checkequal(['', ' startcase'], '| startcase', 'split', '|')
    self.checkequal(['', 'bothcase', ''], '|bothcase|', 'split', '|')
    self.checkequal(['a', '', 'b\x00c\x00d'], 'a\x00\x00b\x00c\x00d', 'split', '\x00', 2)

从测试中可以清楚地看出,执行不同操作的任何实现都会使这些测试失败。

答案 1 :(得分:3)

CPython被认为是Python的参考实现。根据CPython源代码object["property"] 保证按从左到右的顺序拆分。您可以查看str.split的实施方式,这是一个链接http://svn.python.org/view/python/tags/r271/Objects/stringlib/split.h?view=markup

例如,在str.split(以及stringlib_split_char中,stringlib_split_whitespacestringlib_split)中都使用),可以清楚地看到字符串已处理从左到右(str.spliti用于索引字符串,它们都从零开始并递增,j不影响索引的处理方式,{{1} }只提供从循环中提前退出):

maxsplit

maxsplit(用于Py_LOCAL_INLINE(PyObject *) stringlib_split_char(PyObject* str_obj, const STRINGLIB_CHAR* str, Py_ssize_t str_len, const STRINGLIB_CHAR ch, Py_ssize_t maxcount) { // ... some code omitted i = j = 0; while ((j < str_len) && (maxcount-- > 0)) { for(; j < str_len; j++) { /* I found that using memchr makes no difference */ if (str[j] == ch) { SPLIT_ADD(str, i, j); i = j = j + 1; break; } } } // ... some code omitted )中,stringlib_rsplit_charstr.rsplit索引都从字符串末尾开始并递减:

i