Python性能:从列表中删除项目

Nac*_*uel 7 python performance list

我有一个列表,其长度为:370000.在这个列表中,我有以下项目:"a", "y", "Y", "q", "Q", "p", "P",,这意味着这是一个单词列表,但我不时会得到那些单个字符.

我想从列表中删除这些字符,我在python中很新,但我想到的第一件事就是做类似的事情:

for word in words:
    if word== 'm' or  word== 'y' or word== 'Y' or word== 'p' or word== 'Q' or word== 'q' or word== 'a' or word== 'uh':
        words.remove(word)
Run Code Online (Sandbox Code Playgroud)

在一个包含370.000项目的列表中,这种方法正在耗费时间.说真的,很多.

有没有人对如何获得更好的表现有另一个很棒的想法?

提前致谢.

Con*_* Ma 8

在IPython中尝试了一些bogo基准测试.

import random
# Don't know how to generate your words, use integers as substitute.
words = [random.randint(0, 25) for i in xrange(370000)]
badlist = range(7)
badtuple = tuple(badlist)
badset = set(badlist)
# List comprehension
%timeit [w for w in words if w not in badlist]
10 loops, best of 3: 59.2 ms per loop
%timeit [w for w in words if w not in badtuple]
10 loops, best of 3: 64.7 ms per loop
%timeit [w for w in words if w not in badset]
10 loops, best of 3: 30.3 ms per loop
# Filter
%timeit filter(lambda w: w not in badlist, words)
10 loops, best of 3: 85.6 ms per loop
%timeit filter(lambda w: w not in badtuple, words)
10 loops, best of 3: 92.1 ms per loop
%timeit filter(lambda w: w not in badset, words)
10 loops, best of 3: 50.8 ms per loop
Run Code Online (Sandbox Code Playgroud)

结论:使用列表理解not in <set>作为过滤条件可能是最好的.

但正如我所说,这个基准是假的,你需要重复一些关于你会遇到的实际数据的基准,看看哪个更好.


关于为什么列表理解+"不在集合中"的一些想法可能是最优的.

  1. filtervs list comprehension:filter实际上调用输入可调用,Python中的可调用调用有自己的开销(创建堆栈帧等) 同时filter尝试智能并返回正确的类型,这会增加开销.(这实际上是无穷小的)相反,列表理解的条件检查(if ...子句)比调用具有更少的开销.这只是表达式评估,没有Python调用堆栈的完整功能.
  2. 集合成员资格的测试平均情况为O(1),最坏情况下为O(n),但列表/元组成员资格总是O(n).