2

重複の可能性:
Python での反復中にリストからアイテムを削除する

かなり埋め込まれたリストがあります。具体的には、タプルのリストのリストです。簡単にするために、リスト全体は文のリストです。各センテンス内で、各単語はその単語に関する情報を含むタプルになります。各文の最後のタプルには話者に関する情報が含まれていますが、必要に応じて削除できます。

これらのタプルを検索して、特定の値が見つかった場合は、文全体を削除したいと思います。

リストの例を次に示します。

sentenceList = [[('the', 'det', '1|2|DET'), ('duck', 'n', '2|3|SUBJ'), ('xxx', 'unk', '3|0|ROOT'), ('*MOT', 373)],
                [('yyy', 'unk', '1|0|ROOT'), ('*CHI', 375)], 
                [('what', 'pro', '1|2|OBJ'), ('happen-PAST', 'v', '2|0|ROOT'), ('to', 'prep', '3|2|JCT'), ('the', 'det', '4|5|DET'), ('duck', 'n', '5|3|POBJ'), ('*MOT', 378)], 
                [('boom', 'int', '1|0|ROOT'), ('*CHI', 379)]]

文に'xxx'またはが含まれている場合は、文'yyy'全体を削除したいと思います。私が試したコードは次のとおりです。

wordList = ['xxx','yyy']
for sentence in sentenceList:
    for wordTuple in sentence:
        for entry in wordTuple:
            if entry in wordList:
                del sentence

これにより、文全体が削除されます。つまり、次のようになります。

[('the', 'det', '1|2|DET'), ('duck', 'n', '2|3|SUBJ'), ('xxx', 'unk', '3|0|ROOT'), ('*MOT', 373)], [('yyy', 'unk', '1|0|ROOT'), ('*CHI', 375)]

ただし、このコードはタスクを達成していないようです。それを修正する方法はありますか?ありがとう!

4

3 に答える 3

2
wordList = set(('xxx','yyy'))
for sentence in sentenceList[:]:
    removed = False
    for wordTuple in sentence:
        for entry in wordTuple:
            if entry in wordList:
                sentenceList.remove(sentence)
                removed = True
                break
            # end of if
        # end for each entry
        if removed:
            break
    # end for each word tuple
# end for each sentence

ノート:

  • リストの(浅い)コピーを反復処理して、トラバースしているコレクションを変更することで発生するエラーを回避します
  • 変数名をローカル名前空間から単純に削除するのではなく、リストからオブジェクトを削除します
  • これは大規模なデータセットには効率的ではありません
于 2012-08-01T19:35:12.673 に答える
1

でリストを繰り返し処理しているときに、リストを変更しようとするのは危険ですfor。あなたが本当に欲しいのは while ループです:

contrived_data = [[(1, 1, 1), ('hello', 'bar')], [(222, 3, 4), ('norweigan', 'blue')], [('anthrax', 'ripple'), (42, 'life')]]

looking_for = (1, 'life')

index = 0
while index < len(contrived_data):
    for two_pull in contrived_data[index]:
        for item in looking_for:
            if item in two_pull:
                print(contrived_data.pop(index))
                index -= 1
                break # Only jumps out of the innermost loop
    index += 1

また、元のリストをコピーするよりも、大規模なデータセットの方が効率的です。

于 2012-08-01T19:44:18.273 に答える
1

この答えは似ています。それを適用するには、エントリを残すかどうかを決定する述語 ( Trueorのみを返す 1 つの引数の関数) が必要です。False

と呼ばれるセットにターゲット単語があるとしwordListます。

wordList = set(('xxx', 'yyy'))

この述語は機能するはずです。

def keep_sentence(sentence):
    for wordTuple in sentence:
        for entry in wordTuple:
            if entry in wordList:
                return False
    return True  # Only executed if we didn't return false earlier

述語ができたので、の内容を、保持する必要があることを示す文のみに置き換えることができますsentenceListkeep_sentence

sentenceList[:] = [x for x in sentenceList if keep_sentence(x)]

これを大規模なデータセットに適用する限り、コードを並列化せずに、これ (または他の回答の 1 つ) よりもはるかに高速なアルゴリズムはおそらくないでしょう。なんで?各センテンスに対象の単語が含まれていないことを確認するには、各センテンスの各単語を調べる必要があります。各センテンスに費やす時間を一定の割合で減らすことはできるかもしれませんが、それは大きな助けにはなりません。

これに興味がある場合は、multiprocessingモジュール、特にプロセス プールを確認してください。

于 2012-08-01T21:51:09.323 に答える