基于语言测试的阿拉伯语句子过滤列表:为什么这么慢?

Filtering list of Arabic sentences based on language test: Why so slow?

我正在尝试查看(主要是)阿拉伯语句子列表,并删除那些不是阿拉伯语的句子。我有一个判断字符是否为阿拉伯语的技巧:阿拉伯语没有大小写,所以如果字符是字母但不是大写或小写,它就是阿拉伯语。

我有下面的代码,它可以工作,但是与其他过滤器相比,语言识别部分非常慢。在我看来它并没有做任何特别复杂的事情,所以我不明白为什么要花这么长时间。 (过滤前语料库大小约为300K个句子。)

我可以做些什么来提高效率吗?

谢谢!

def test_lang(string):
    """Takes a string and determines if it is written in Arabic 
    characters or foreign, by testing whether the first character 
    has a case attribute. This is intended for Arabic texts that  
    may have English or French words added. If it encounters another 
    case-less language (Chinese for instance), it will falsely 
    identify it as Arabic."""

    if not string or not string.isalpha():
        return None
    char = string[0]
    if char.isalpha() and not (char.islower() or char.isupper()):
        lang = 'AR'
    else:
        lang = 'FW'
    return lang

...

# remove sentences that are in English or French - THIS IS SLOW (takes a few mins)
for sent in sents:
    if sent and test_lang(sent[0]) != 'AR':
        sents.remove(sent)

# remove clearly MSA sentences -- THIS IS FAST (takes a few seconds)
msa_features = ['ليس','لست','ليست','ليسوا','الذي','الذين','التي','ماذا', 'عن']
p = re.compile('|'.join(msa_features))
for sent in sents:
    if re.search(p, sent):
        sents.remove(sent)

list.remove 为此目的非常慢 - 它每次都在整个列表中搜索给定值,然后将其删除。它必须为每个被删除的元素有效地遍历整个列表,从而导致二次运行时间。

此处更好的解决方案是以下列表表达式:

sents = [
    sent for sent in sents
    if test_lang(sent[0]) == 'AR' and not re.search(p, sent)
]

这会在线性时间内过滤列表。

(我猜第一个过滤器必须对一个很长的列表进行操作并丢弃其中的大部分?而第二个过滤器接收一个小得多的列表并且不必删除太多?这可以解释为什么第一个慢得多。)