我有一个相当嵌入的列表:具体来说,它是元组列表的列表。为简化起见,整个列表是一个句子列表。在每个句子中,每个单词都被组成一个元组,其中包含有关该单词的信息。每个句子中的最后一个元组包含有关说话者的信息,但如果需要可以删除。
我想搜索这些元组,如果找到某个值,则删除整个句子。
以下是一个示例清单:
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)]
但是,此代码似乎没有完成任务。知道怎么解决吗?谢谢!
答案 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类似。要应用它,我们需要一个谓词(一个只返回True
或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
告诉我们应该保留的句子替换keep_sentence
的内容:
sentenceList[:] = [x for x in sentenceList if keep_sentence(x)]
至于将其应用于大型数据集 - 如果不并行化代码,可能不会有比这更快的算法(或其他答案之一)。为什么?为了检查每个句子是否包含一个目标词,我们必须查看每个句子中的每个词。你可以通过一些常数因素减少你在每个句子上花费的时间,但这不会有很大的帮助。
如果您对此感兴趣,可以查看multiprocessing
模块,尤其是process pools。