2017-08-07 14 views
2
for x,y in words: 
    for z in x: 
     if z in stopwords: 
      del x[x.index(z)] 

これは私のコードです。delはリストから何も削除していないようです

(list of words, metadata) 

私のコードの目的は、単語のリストからすべてのストップワードを削除することです:言葉のデータはタプルは次のようになりタプルのリストです。 これは唯一の問題は、ストップワードが後で削除されないことです...

私は間違って何をしましたか? 私はすでに

x.pop(x.index(z)) 

でそれを実行しようとしましたが、それは違いを確認していないようです。例えば

stopwords = set(stopwords) # just so "in" checks are faster 
result = [([word for word in x if word not in stopwords], y) for x, y in words] 

>>> stopwords = ['stop'] 
>>> words = [(['hello', 'you', 'stop'], 'somemeta')] 
>>> stopwords = set(stopwords) # just so "in" checks are faster 
>>> result = [([word for word in x if word not in stopwords], y) for x, y in words] 
>>> result 
[(['hello', 'you'], 'somemeta')] 

注あなたは、一般的にリストあなた」を変更しないでください

+3

反復処理中にリストからデータを削除するのは良い考えではないため、定義されていない動作が発生する可能性が高くなります。代わりにあなたの問題をリスト内包として定式化し、あなたの基準に合致する新しいリストを作成しようとします。 –

+0

単語とストップワードの例を挙げてください – nacho

答えて

4

あなたは、単にネストされたリストの内包表記を使用してストップワードなしで新しいリストを作成することができます繰り返すそれはバグを追跡するのが大変なことにつながります。

+0

ストップワードのセットを作成する理由を説明してもらえますか?私はコメントが分かりません。 – DrBwts

+2

メンバーシップテストの(恒例の)漸近的ランタイムは、リストやタプルなどの他のコンテナの場合は 'O(n)'です(https:// wikiも参照してください)。 python.org/moin/TimeComplexity)。そして、特にinのチェックが内側のループで行われるので、潜在的な節約は膨大になる可能性があります。 – MSeifert

0
for x,y in words: 
    for z in x: 
     if z in stopwords: 
      del x[x.index(z)] 

最も外側のループは、単語リストの1つにxを割り当てます。我々はすぐにyを無視します。 2番目のループはその単語リストを繰り返します。 removing elements from a list you're iterating over causes peculiar behaviour。特定の単語をスキップする可能性があります。これは、del、pop、removeおよびsliceのすべての置換に適用されます。

stopwordssetであることを保証し、それに基づいて各単語をフィルタリングすると、内部ループの代わりにx[:] = [w for w in x if w not in stopwords]が効率的になります。ここでのスライス置換は、純粋にxが同じオブジェクトのままであることを保証するためのものであり、この場合はwords内のエントリを確実に変更します。 これは、前述の反復問題には実行されません。なぜなら、リストの理解は、割り当てによってスライスに格納される前にそのリストを構築するためです。

関連する問題