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


120

'/segment/segment/'.split('/')帰る意味は['', 'segment', 'segment', '']

空の要素に注目してください。たまたま位置1で文字列の最後にある区切り文字で分割している場合、両端から空の文字列が返されるようにするには、どのような余分な値が必要ですか?


1
同じ質問があり、長い間検索していました。空の結果が非常に重要であることを理解しました。ご質問ありがとうございます。
emeraldhieu

2
解決策は、使用することですstrip()、分割前の文字列から先頭と末尾の分割文字を削除する:'/segment/segment/'.strip('/').split('/')
pkamb

回答:


178

str.split補完するstr.joinので、

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

元の文字列に戻します。

空の文字列がそこになかった場合、最初と最後'/'は、join()


11
シンプルですが、質問に完全に答えます。
オロクサキ

中かっこが実際にPythonで有効であることを発見して、私はショックを受けました... ドキュメントはこれについて言及していないようです。
Tim Pietzcker、2012年

@ティム、私はそれらの引用がどのようにそこに入ったのか分かりません:/
John La Rooy

7
では、Microsoft WordをPython IDEとして使用していませんか?:)
Tim Pietzcker

1
単純な答えは最高ではなかったと言った@ aaa90210?それは答えが簡単であるというコメント(最初は5年前)でしたが、完全に質問に答えました。文に「but」を使用しても、悪いことは何もありません。単純ではない回答は、より完全な回答である可能性があります(たとえば、関連する決定や、言及された機能に関連するPEPを含む)。
orokusaki

88

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

例:

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

戻り値

['segment', 'segment']

3
これをありがとう、なぜこの答えがこれほど遠いのかわからない、他のすべては初歩的なものです。
ウェッジ

6
フィルターオブジェクトを出力として取得するのではなく、リストに結果を収集する場合は、フィルター構造全体をに配置しlist(...)ます。
TimVisée2017年

29

ここで考慮すべき主な点が2つあります。

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

結局、それは2つのことに要約されます:

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

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

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

しかし、空の値を無視したくない場合、できるはずです。

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

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


重複するスペースをnukeしてから分割する方が速いのか、それとも分割して空でない文字列のみを取得する方が速いのか疑問に思う方のために、以下を取得しますpython3 -m timeit "import re ; re.sub(' +', ' foo bar baz ', '').split(' ')"。->ループあたり875ナノ秒。python3 -m timeit "[token for token in ' foo bar baz '.split(' ') if token]"->ループあたり616
ナノ秒

8

持っx.split(y)いつものリストを返す1 + x.count(y)@ gnibblerさんはすでに落札指摘したように-アイテムは貴重な規則性であるsplitjoin(彼らは明らかであるべきと)お互いの正確な逆で、それも正確に(区切り文字に参加しているレコードのすべての種類の意味をマップします以下のようなcsvファイルの行[[引用問題のネット]]、からライン/etc/groupローマの答えが述べた@としてのUnixで、など)、それは、ファイルパスやURLでの相対パス()対のための簡単なチェック(例えば)絶対)(ことができますなど。

それを見る別の方法は、利益を得るためにウィンドウから情報を投げ捨てるだけではいけないということです。とx.split(y)同等のものにすることで何が得られx.strip(y).split(y)ますか?何も、もちろん-それはそれはあなたが何を意味するかだときに、第2のフォームを使用するのは簡単ですませんが、最初のフォームを任意秒1を意味するものとみなされた場合は、とき、あなたがやるべき仕事がたくさんあると思います(最初のものが欲しいです前の段落で指摘したように、これはまれではありません。

しかし、実際には、数学的な規則性の観点から考えることが、合格可能なAPIを設計するための最も簡単で最も一般的な方法です。別の例をとるには、有効なxandが非常に重要です。y x == x[:y] + x[y:]これは、スライスの1つの極端を除外する必要がある理由をすぐに示します。作成できるインバリアントアサーションが単純であるほど、結果のセマンティクスは実際の使用に必要なものであると考えられます。つまり、数学は宇宙の扱いに非常に役立つという神秘的な事実の一部です。

split先頭と末尾の区切り文字が特殊なケースである方言の不変式を定式化してみてください...反例:次のような文字列メソッドisspaceは最大限に単純ではありません- x.isspace()に相当しますx and all(c in string.whitespace for c in x)-ばかげた先導x andがコーディングを見つけやすい理由ですnot x or x.isspace()、文字列メソッドに設計されるべきであった単純さを取り戻すためにis...(空の文字列はあなたが望むものであり、それによって通りの馬の感覚に反して、おそらく[[空のセット、ゼロのように&c、ほとんどの人を常に混乱させてきました;-)]]ですが、明確で洗練された数学的常識に完全に準拠しています!-)。


5

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

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

4
-1は3つのマッチではなく4つのマッチを取得し、これは実際には質問に答えないためです。
ローマ、

1
ネガを打ち消すために+1。彼はあなたが3つの結果を取り戻すとは言っていませんでした。彼は「3つの区切り文字」に対して「3つの一致」と言ったが、これは私には論理的に聞こえる。ただし、「4つの一致」はありません。ただし、結果には「4つの要素」が返されます。また、「なぜ」に直接答えることはありませんが、彼が本当に望んでいるものを取得するための簡単な方法を提供します...私はこれに反対する価値はないと思います。あなたが誰かに反対票を投じるつもりなら(反対票も含めて)、もっと注意してください!乾杯!8 ^)
kodybrown 2013

@wasatchwizard説明をありがとう。訂正、推薦をお願いします。残念ながら、私の投票はロックされており、変更することはできません。
ローマ

私はあなたのソリューションが大好きです-ストリップしてから分割して空の結果を削除します
Nam G VU

5

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

簡単な例:絶対ファイル名と相対ファイル名を確認したいとします。この方法では、ファイル名の最初の文字が何であるかを確認する必要もなく、スプリットですべてを行うことができます。


1

この最小限の例を考えてみましょう:

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

splitdelimiterの前後に何があるかを示す必要'/'がありますが、他の文字はありません。それはそう持っているあなたに技術的に先行し、次の空の文字列、与える'/'ので、を'' + '/' + '' == '/'

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.