替换长列表Python中的元素

2024-06-25 06:21:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用一个标记替换一个更大的列表(300万个元素)中的一些元素(大约40k)。下面的代码可以工作,但是速度非常慢

def UNKWords(words):
    words = Counter(words)
    wordsToBeReplaced = []
    for key, value in words.items():
        if(value == 1):
            wordsToBeReplaced.append(key)
    return wordsToBeReplaced

wordsToBeReplaced = UNKWords(trainingWords)

replacedWordsList = ["<UNK>" if word in wordsToBeReplaced else word for word in trainingWords]

有没有更有效的方法来替换这么大的列表中的元素


Tags: key代码in标记元素列表forif
3条回答

你可以避开计数器,只需记录你见过多次的单词,就可以挤出更多的性能。这将有效地从函数中删除一个循环,并允许您收集在单个循环中多次看到的单词:

def UNKWords(words):
    seen = set()
    kept = set()
    for word in words:
        if word in seen:
            kept.add(word)
        else:
            seen.add(word)
    return kept

def replaceWords(words):   
    wordsToKeep = UNKWords(trainingWords)
    return ["<UNK>" if word not in wordsToKeep else word for word in trainingWords]

…然后使用集合而不是列表来测试成员资格,正如其他人所提到的,因为它们允许进行固定时间的成员资格测试

您可以将wordsToBeReplaced设置为一个集合,这样可以在平均恒定时间而不是线性时间内进行查找:

def UNKWords(words):
    return {word for word, count in Counter(words).items() if count == 1}

除了@blhsing的回答,我建议使用一个冰冻套;同时进行替换(当然,除非出于其他目的需要保留原始列表):

def UNKWords(words):
    return frozenset(word for word, count in Counter(words).items() if count == 1)

wordsToBeReplaced = UNKWords(trainingWords)
for i, word in enumerate(trainingWords):
    if word in wordsToBeReplaced:
        trainingWords[i] = '<UNK>'

相关问题 更多 >