2009-03-17 9 views
2

私は、指定された句読点を無視して、テキストを単語に分割するPython関数を書いています。ここにいくつかの作業コードがあります。私はリストから文字列を構築することは効率的であると確信していません(コード中のbuf = [])。誰かがこれを行うためのよりよい方法の提案をしていますか?Pythonで文字列に反復的に追加する有効な方法はありますか?

def getwords(text, splitchars=' \t|!?.;:"'): 
    """ 
    Generator to get words in text by splitting text along specified splitchars 
    and stripping out the splitchars:: 

     >>> list(getwords('this is some text.')) 
     ['this', 'is', 'some', 'text'] 
     >>> list(getwords('and/or')) 
     ['and', 'or'] 
     >>> list(getwords('one||two')) 
     ['one', 'two'] 
     >>> list(getwords(u'hola unicode!')) 
     [u'hola', u'unicode'] 
    """ 
    splitchars = set(splitchars) 
    buf = [] 
    for char in text: 
     if char not in splitchars: 
      buf.append(char) 
     else: 
      if buf: 
       yield ''.join(buf) 
       buf = [] 
    # All done. Yield last word. 
    if buf: 
     yield ''.join(buf) 
+0

あまりにも悪い...ここには、最高の答えを入れて、組み込みのスプリットが複数のスプリッチを置くことができると言った人がいました。 彼のコードは醜いと言って、彼はメッセージを削除しました。 – fulmicoton

答えて

3

を使用することができます

re.split('[\s|!\?\.;:"]', text) 

しかし、テキストが非常に大きい場合、結果の配列が多すぎるメモリを消費している可能性があります。次に、あなたはre.finditerを検討するかもしれません:

import re 
def getwords(text, splitchars=' \t|!?.;:"'): 
    words_iter = re.finditer(
    "([%s]+)" % "".join([("^" + c) for c in splitchars]), 
    text) 
    for word in words_iter: 
    yield word.group() 

# a quick test 
s = "a:b cc? def...a||" 
words = [x for x in getwords(s)] 
assert ["a", "b", "cc", "def", "a"] == words, words 
4

re.splitを使用したくないですか? Pythonで文字列を連結し、同様に彼らのパフォーマンスを評価するいくつかの方法について

import re 
re.split("[,; ]+", "coucou1 , coucou2;coucou3") 
+0

それはまったく考えられませんでした。それを考えます。ありがとう! –

5
+0

これは私が必要としていたものです。ありがとう。 cStringIOは、私のユースケースにとって最良の選択肢です。 –

+0

ああ。 cStringIOはUnicode文字列を処理できません。 –

+0

これは価値があります:Python 2.5をインストールするまで、そのテストケースをハッキングし、メソッド6(フィード ''。リストの理解に参加すること)が一貫して最速であることがわかりました。 6のジェネレータの表現は*遅くなっていますが、それでも2番目に高速です。 – kquinn

1

あなたはre.split()を使用して入力を分割することができます:

>>> splitchars=' \t|!?.;:"' 
>>> re.split("[%s]" % splitchars, "one\ttwo|three?four") 
['one', 'two', 'three', 'four'] 
>>> 

はEDIT:あなたのsplitchars]または^などの特殊文字が含まれている可能性がある場合、あなたはあなたがre.splitを使用することができますre.escpae()

>>> re.escape(splitchars) 
'\\ \\\t\\|\\!\\?\\.\\;\\:\\"' 
>>> re.split("[%s]" % re.escape(splitchars), "one\ttwo|three?four") 
['one', 'two', 'three', 'four'] 
>>> 
関連する問題