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'or '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的参数的函数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

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

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

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

如果您对此感兴趣,您可能想查看该multiprocessing模块,尤其是进程池

于 2012-08-01T21:51:09.323 回答