web-dev-qa-db-ja.com

split()の結果で空の文字列が返されるのはなぜですか?

'/segment/segment/'.split('/')が返すポイント['', 'segment', 'segment', '']

空の要素に注意してください。文字列の位置1と最後にある区切り文字で分割している場合、各文字列から空の文字列が返されるためにどのような追加の値が与えられますか?

97
orokusaki

_str.split_は_str.join_を補完するため、

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

元の文字列を取得します。

空の文字列がない場合、join()の後に最初と最後の_'/'_がありません

144
John La Rooy

より一般的には、split()の結果で返された空の文字列を削除するには、 filter 関数を調べます。

例:

filter(None, '/segment/segment/'.split('/'))

返す

['segment', 'segment']
46

ここで考慮すべき2つの主なポイントがあります。

  • '/segment/segment/'.split('/')の結果が_['segment', 'segment']_と等しくなることを期待するのは合理的ですが、これにより情報が失われます。 split()が望みどおりに動作した場合、a.split('/') == ['segment', 'segment']であると言った場合、aが何であったかを知ることはできません。
  • 'a//b'.split()の結果はどうなりますか? _['a', 'b']_ ?、または_['a', '', 'b']_?つまり、split()は隣接する区切り文字をマージする必要がありますか?必要な場合は、文字で区切られたデータを解析するのが非常に難しくなり、一部のフィールドは空になります。 do上記の場合の結果に空の値が必要な人がたくさんいると確信しています!

最終的には、次の2つに要約されます。

一貫性:n区切り文字がaにある場合、split()の後に_n+1_値が返されます。

複雑なことも簡単なこともできるはずです。split()の結果として空の文字列を無視したい場合は、いつでもできます。

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

ただし、空の値を無視したくない場合は、1つshouldを使用できます。

言語はsplit()の定義を1つ選択する必要があります。デフォルトとして全員の要件を満たすには、あまりにも多くの異なるユースケースがあります。 Pythonの選択は良い選択であり、最も論理的だと思います。 (余談ですが、Cのstrtok()が嫌いな理由の1つは、隣接する区切り文字をマージするため、深刻な解析/トークン化を行うことが非常に困難になることです。)

例外が1つあります。引数のないa.split()は連続した空白を絞りますが、その場合はこれが正しいことだと主張できます。動作を望まない場合は、いつでもa.split(' ')にできます。

27
Alok Singhal

x.split(y)が常に1 + x.count(y)アイテムのリストを返すことは貴重な規則性です。@ gnibblerがすでに指摘しているように、splitjoinが完全に逆になります相互に(明らかにそうであるように)、すべての種類の区切り文字に結合されたレコードのセマンティクス(csvファイル行[[引用の問題のネット]]、_/etc/group_(Unixなど)、(@ Romanの答えとして)絶対パスと相対パス(ファイルパスとURL)などの簡単なチェックなどが可能です。

別の見方をすれば、情報を窓から放り出すだけで利益を得ることはできません。 x.split(y)x.strip(y).split(y)と同等にすることで何が得られますか?もちろん、2番目のフォームを使用するのは簡単です。ただし、最初のフォームが2番目のフォームを意味すると見なされる場合、多くの作業が必要になりますdo最初のものが必要です(前の段落が指摘しているように、これはめったにありません)。

しかし、実際には、数学的な規則性の観点から考えることは、まずまずのAPIを設計するための最も簡単で最も一般的な方法です。別の例を挙げると、有効なxおよびy _x == x[:y] + x[y:]_が非常に重要です。これは、スライスの極端な理由をすぐに示すものです。 除外されます。定式化できる不変のアサーションが単純であればあるほど、結果のセマンティクスは実際の使用に必要なものである可能性が高くなります-数学は宇宙を扱うのに非常に役立つという神秘的な事実の一部です。

先頭と末尾の区切り文字が特殊な場合のsplit方言の不変式を定式化してみてください...反例:isspaceなどの文字列メソッドは最大限単純ではありません-x.isspace()x and all(c in string.whitespace for c in x)と同等です-愚かな先頭の_x and_がnot x or x.isspace()のコーディングを頻繁に見つける理由であり、単純さshouldは、_is..._文字列メソッドに設計されています(空の文字列は、必要に応じて「すべて」です。ゼロ&cのような空のセットは、ほとんどの人を常に混乱させています;-)]]、しかし明確で洗練された数学的な常識に完全に準拠しています!-)。

7
Alex Martelli

あなたがどのような答えを探しているのか分かりませんか? 3つの区切り文字があるため、3つの一致が得られます。その空のものが必要ない場合は、単に使用します:

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

さて、そこに区切り文字があったことがわかります。したがって、4つの結果を見ると、区切り文字が3つあることがわかります。これにより、Python空の要素を削除してから、必要に応じて区切り文字の開始または終了を手動で確認するのではなく、この情報で必要なことを行うことができます。

簡単な例:絶対ファイル名と相対ファイル名を確認するとします。この方法では、ファイル名の最初の文字が何であるかを確認することなく、分割ですべてを実行できます。

5
Roman