2016-07-01 8 views
1

the Python 2.7 docsによれば、str.split()maxsplitと指定すると、maxsplit回までの文字列が分割されます。str.split()の分割順序は保証されていますか?

ただし、これらの分割が左から右に実行されることは明示的に指定されていません。右から左への分割注文を保証する関連機能str.rsplit()があります。

左から右に分割する順序を保証する方法はありますか?str.rsplit()の後に文字列を逆順で並べる以外にも、 str.split()が左から右の順序を使用しない状況がありますか?

+5

'str.split'は常に.rsplit'他の方法 '、左から右へ分岐します。 – jonrsharpe

+0

これはドキュメントでは決して指定されていません。あなたの保証はどこにありますか?私は経験的にはこれが結果だと理解していますが、観察は保証ではありません。 – Connor

+2

@ConnorBlanck - あなたが望むなら、あなたは実装を見て自由です。 ltr分割はメソッドの意図です - 分割が発生することがわからない場合、 'maxsplit'はほとんど使用されません。私は、文書作成者があまりにも明白であることが言及したことをちょうど見つけたと推測している。ドキュメントにこれが必要であると思われる場合は、ドキュメントにバグを提出してください。 – mgilson

答えて

3

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) 

テストから、別の何かをした任意の実装はこれらのテストを失敗するだろうことは明らかです。

+0

これはかなり良い保証です。私は、この仮定を指定するためにドキュメントを入手する方法について見ていきます。ありがとう。 – Connor

2

CPythonはPythonのリファレンス実装と見なされます。 CPythonソースコードstr.splitによると、左から右の順に分割されていることが保証されています。あなたは1つが、文字列がから加工されていることをはっきりと見ることができ、ここで(両方stringlib_splitstr.split)で使用されているstringlib_split_whitespaceのようにも、)stringlib_split_char内のリンクたとえばhttp://svn.python.org/view/python/tags/r271/Objects/stringlib/split.h?view=markup

が、ある、どのように実装されるかstr.split調べることができます左から右へ(ij文字列のインデックスに使用され、それらの両方がゼロで開始し、インクリメントされ、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 

そして(str.rsplitで使用)両方ijインデックスは、文字列の最後に開始してデクリメントされる:

i = j = str_len - 1; 
while ((i >= 0) && (maxcount-- > 0)) { 
    for(; i >= 0; i--) { 
     if (str[i] == ch) { 
      SPLIT_ADD(str, i + 1, j + 1); 
      j = i = i - 1; 
      break; 
     } 
    } 
+1

* "how [it]が実装されています" *は**実装されている実装で保証されているかどうかと同じではありません。 – jonrsharpe

+0

cpythonはPython言語のリファレンス実装とみなされます – NickAb

+0

*と考えられます。あなたはそれを答えに入れて、それが* a *ではないことに注意してください! – jonrsharpe

関連する問題