Python:搜索元组列表,删除整个索引

时间:2012-08-01 19:27:53

标签: python list nlp

  

可能重复:
  Remove items from a list while iterating in 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)]

但是,此代码似乎没有完成任务。知道怎么解决吗?谢谢!

3 个答案:

答案 0 :(得分: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

注意:

  • 遍历列表的(浅)副本以避免因修改您正在遍历的集合而产生的错误
  • 从列表中删除对象,而不是简单地从本地命名空间中删除变量名称
  • 这对大型数据集无效

答案 1 :(得分: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

对于较大的数据集而言,这比复制原始列表更有效。

答案 2 :(得分:1)

This answer类似。要应用它,我们需要一个谓词(一个只返回TrueFalse的参数的函数)来确定条目是否应该保留。

鉴于我们在名为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

现在我们有一个谓词,我们可以用sentenceList告诉我们应该保留的句子替换keep_sentence的内容:

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

至于将其应用于大型数据集 - 如果不并行化代码,可能不会有比这更快的算法(或其他答案之一)。为什么?为了检查每个句子是否包含一个目标词,我们必须查看每个句子中的每个词。你可以通过一些常数因素减少你在每个句子上花费的时间,但这不会有很大的帮助。

如果您对此感兴趣,可以查看multiprocessing模块,尤其是process pools