Pythonでコンマで分割し、空白を取り除く


346

私はコンマで分割するいくつかのpythonコードを持っていますが、空白を取り除きません:

>>> string = "blah, lots  ,  of ,  spaces, here "
>>> mylist = string.split(',')
>>> print mylist
['blah', ' lots  ', '  of ', '  spaces', ' here ']

私はむしろこのように空白を削除してしまうでしょう:

['blah', 'lots', 'of', 'spaces', 'here']

リストをループして各項目をstrip()できることは承知していますが、これはPythonなので、より速く、簡単で、よりエレガントな方法があると思います。

回答:


594

リスト内包表記を使用する- forループよりも簡単で読みやすい。

my_string = "blah, lots  ,  of ,  spaces, here "
result = [x.strip() for x in my_string.split(',')]
# result is ["blah", "lots", "of", "spaces", "here"]

参照: リスト内包に関するPythonのドキュメント
リスト内包についての2秒のわかりやすい説明。


1
すっごくいい!空白のリストエントリを削除するために、次のように1つの項目を追加しました。> text = [text.split( '。')のxに対するx.strip()if x!= '']
RandallShanePhD

@Sean:無効または不完全なPythonコードは「投稿の本来の目的」でしたか?レビューワンカーによると、それはstackoverflow.com/review/suggested-edits/21504253でした。それらが間違っている場合は(もう一度)修正を加えて、そうでないことを教えてもらえますか?
飼料:

元は(私の記憶が正しければ)REPLからコピー&ペーストして、ゴールには(操作を実行するには、リストの内包表記を使用して)基本的な概念を理解して-しかし、あなたがあれば、あなたは正しい、それはより多くの意味を成している参照して、そのリストの内包表記を新しいリストを作成します。
Sean Vieira

24

正規表現を使用して分割します。先行スペースでケースをより一般的にしたことに注意してください。リスト内包は、前後のヌル文字列を削除することです。

>>> import re
>>> string = "  blah, lots  ,  of ,  spaces, here "
>>> pattern = re.compile("^\s+|\s*,\s*|\s+$")
>>> print([x for x in pattern.split(string) if x])
['blah', 'lots', 'of', 'spaces', 'here']

これ^\s+は、一致しない場合でも機能します。

>>> string = "foo,   bar  "
>>> print([x for x in pattern.split(string) if x])
['foo', 'bar']
>>>

^ \ s +が必要な理由は次のとおりです。

>>> pattern = re.compile("\s*,\s*|\s+$")
>>> print([x for x in pattern.split(string) if x])
['  blah', 'lots', 'of', 'spaces', 'here']

何とか先頭のスペースを見てください。

明確化:上記はPython 3インタープリターを使用していますが、Python 2でも結果は同じです。


8
私は[x.strip() for x in my_string.split(',')]尋ねられた質問に対してよりパイソン的であると信じています。多分私の解決策が必要な場合があります。このコンテンツを見つけたら更新します。
tbc0 14

なぜ^\s+必要なのですか?私はそれなしであなたのコードをテストしました、そしてそれは機能しません、しかし私はなぜかわかりません。
laike9m 2015

私が使用する場合re.compile("^\s*,\s*$")、結果は[' blah, lots , of , spaces, here ']です。
laike9m

@ laike9m、私はあなたに違いを示すために私の答えを更新しました。^\s+作る。ご覧のとおり、^\s*,\s*$目的の結果も返されません。したがって、正規表現で分割したい場合は、を使用してください^\s+|\s*,\s*|\s+$
tbc0

先頭のパターン(^ \ s +)が一致しない場合、最初の一致は空なので、文字列 "foo、bar"に対して[''、 'foo'、 'bar']のような結果が得られます。
スティーブマッコーリー

21

追加するようになりました:

map(str.strip, string.split(','))

しかし、それはジェイソン・オレンドルフによってコメントですでに言及されていたのを見ました。

同じ答えでGlenn Maynardのコメントを読んで、マップ上のリストの理解を示唆しているので、なぜだろうと思い始めました。私は彼がパフォーマンスの理由を意味するものだと思っていましたが、もちろん彼はスタイルの理由や何か他のもの(Glenn?)を意味したのかもしれません。

したがって、3つのメソッドをループで適用する私のボックスでの迅速な(おそらく欠陥がある?)テストは明らかになりました。

[word.strip() for word in string.split(',')]
$ time ./list_comprehension.py 
real    0m22.876s

map(lambda s: s.strip(), string.split(','))
$ time ./map_with_lambda.py 
real    0m25.736s

map(str.strip, string.split(','))
$ time ./map_with_str.strip.py 
real    0m19.428s

map(str.strip, string.split(','))彼らはすべて同じ球場にいるようですが、勝者を作ります。

確かに、マップ(ラムダの有無にかかわらず)は、パフォーマンス上の理由から必ずしも除外する必要はありません。私にとっては、少なくともリスト内包と同じくらい明確です。

編集:

Ubuntu 10.04上のPython 2.6.5


15

分割する前に、文字列から空白を削除してください。

mylist = my_string.replace(' ','').split(',')

10
コンマで区切られたアイテムにスペースが埋め込まれている場合の問題の例"you just, broke this"
Robert Rossney、2011年

1
Geeze、これには-1。あなたたちはタフです。それは彼の問題を解決しました、彼のサンプルデータが単一の単語だけであり、データがフレーズであるという仕様はありませんでした。しかし、w / e、私はあなたたちがここで転がる方法だと思います。
user489041 2010年

とにかく、ユーザーに感謝します。公平を期すために、私は特にsplitを要求し、次にstrip()とstripは、先頭と末尾の空白を削除し、その間の何にも触れません。わずかな変更とあなたの答えは完全に機能しますが、mylist = mystring.strip()。split( '、')ですが、これが特に効率的かどうかはわかりません。
Mr_Chimp

12

私はこれがすでに答えられていることを知っていますが、これをたくさんやるのであれば、正規表現が良い方法かもしれません:

>>> import re
>>> re.sub(r'\s', '', string).split(',')
['blah', 'lots', 'of', 'spaces', 'here']

\s任意の空白文字に一致し、空の文字列に置き換えるだけ''です。詳細については、http//docs.python.org/library/re.html#re.subをご覧ください。


3
あなたの例はスペースを含む文字列では機能しません。「for、example this、one」は「for」、「examplethis」、「one」になります。それが悪い解決策であると言っているわけではありません(私の例では完全に機能します)それは単に手元のタスクに依存しています!
Mr_Chimp

ええ、それはとても正しいです!スペースを含む文字列を処理できるように正規表現を調整することもできますが、リスト内包表記が機能する場合は、それを使用します;)
Brad Montgomery

2
import re
result=[x for x in re.split(',| ',your_string) if x!='']

これでうまくいきます。


2

re (正規表現のように)一度に複数の文字を分割できます:

$ string = "blah, lots  ,  of ,  spaces, here "
$ re.split(', ',string)
['blah', 'lots  ', ' of ', ' spaces', 'here ']

これはサンプル文字列ではうまく機能しませんが、コンマとスペースで区切られたリストではうまく機能します。文字列の例では、re.splitパワーを組み合わせて正規表現パターンを分割し、「this-or-that分割」効果を得ることができます。

$ re.split('[, ]',string)
['blah',
 '',
 'lots',
 '',
 '',
 '',
 '',
 'of',
 '',
 '',
 '',
 'spaces',
 '',
 'here',
 '']

残念ながら、それは醜いですが、これでfilterうまくいきます:

$ filter(None, re.split('[, ]',string))
['blah', 'lots', 'of', 'spaces', 'here']

出来上がり!


2
なぜre.split(' *, *', string)ですか?
Paul Tomblin、2015年

4
@PaulTomblinいい考え。これを行うこともできます:re.split('[, ]*',string)同じ効果のため。
Dannid 2015年

Dannidは、@ tbc0の回答のように、冒頭と末尾の空白を削除しないことに気付いた。
Paul Tomblin、2015年

@PaulTomblinheh、そして私の反論[, ]*はリストの最後に空の文字列を残します。フィルタはまだそこに投入するのに良いものだと思います、またはトップの回答のようにリストの理解に固執します。
Dannid 2015年

1

map(lambda s: s.strip(), mylist)明示的にループするよりも少し良いでしょう。または、一度に全部について:map(lambda s:s.strip(), string.split(','))


10
ヒント:map特にを使用lambdaしている場合は、リストの内包表記を使用する必要があるかどうかを再確認してください。
Glenn Maynard

11
ラムダはで回避できmap(str.strip, s.split(','))ます。
Jason Orendorff、2010年


1
import re
mylist = [x for x in re.compile('\s*[,|\s+]\s*').split(string)]

単に、コンマ、または前後の空白の有無にかかわらず、少なくとも1つの空白。

してみてください!


0

map(lambda s: s.strip(), mylist)明示的にループするよりも少し良いでしょう。
または、一度に全部について:

map(lambda s:s.strip(), string.split(','))

これが基本的に必要なものすべてです。

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