Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python性能:从列表中删除项_Python_Performance_List - Fatal编程技术网

Python性能:从列表中删除项

Python性能:从列表中删除项,python,performance,list,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'

我有一个长度为:
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)
在一个包含370000项的列表中,这种方法花费了大量的时间。说真的,很多

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


提前感谢。

您可以使用列表理解,例如:

words = [word for word in words if word not in ["a", "y", "Y", "q", "Q", "p", "P", "uh"]]
列表理解倾向于提供更好的性能

编辑(感谢丛马的结果):

似乎最好的性能来自于使用
作为筛选序列,因此您需要更类似于:

words = [word for word in words if word not in set(("a", "y", "Y", "q", "Q", "P", "uh"))]

在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
结论:使用
不在
的列表理解作为过滤条件可能是最好的

但正如我所说的,这个基准是假的,你需要对你将遇到的实际数据类型重复一些基准,看看哪个更好


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

  • filter
    vs list comprehension:
    filter
    实际上调用了可调用的输入,Python中的可调用调用有其自身的开销(创建堆栈帧等)。此外
    filter
    尝试变得聪明并返回正确的类型,这会增加开销。(这实际上是无限小的)相反,列表理解的条件检查(if…
  • 子句)比调用的开销更小。它只是表达式求值,没有Python调用堆栈的全部细节
  • 集合成员的测试在平均情况下是O(1),在最坏情况下是O(n),但列表/元组成员始终是O(n) “但有时我会看到这些单一的角色。”

    我认为这里的逻辑很糟糕。在列表中插入单词时,应该将其删除。毕竟,在冗长的列表之后删除它是一个糟糕的选择

    我也遇到过同样的问题,起初我的解决方案是使用


    我认为pypy当时有问题(我的代码突然退出),所以我用更好的逻辑更改代码,并使用普通python;这个有一个简单的应用程序。生成器具有良好的性能,并且通常可以减少内存使用,因为管道不会创建巨大的临时列表(尽管我的最终列表违反了这一原则)


    当你有足够的内存时,动态修改列表并不是一个好主意,很容易像命令所说的那样出错

    至于性能,
    list.remove
    是一个O(n)操作,因此您的代码是O(n^2)

    列表理解要快得多,因为它需要更多的空间——在Python3中创建一个新的列表/或生成器,使用一个小的黑名单过滤掉最终结果。虽然我不确定它是否每次都会创建
    [“a”、“y”、“y”、“q”、“q”、“p”、“p”、“uh”]
    ,但丛玛删除的回答中提到首先创建这个小集合(是的集合,集合中的()是O(1)操作!),这可能对性能有帮助

    而且,列表理解比我之前的测试中的
    map
    list(map(something))
    慢25%,我现在无法证明这一点,但您可能需要进行测试


    如果Python中的所有功能都完成了,并且性能仍然不能满足生产要求,那么Pypy/Cython将是最终的解决方案。

    这不仅仅是性能问题;你也会跳过单词。看看你从哪里得到数据?随机文本。只是为了好玩,应该比
    filter()
    快一点。我想在列表comp中创建集合可能不是非常有效的方法,而且
    words[:]=…
    将更改原始列表我临时删除了我的答案以防止编辑。我添加了一些基准测试(虽然是假的,因为我使用了一些数字而不是字符串,因为我们没有OP的数据)。@CongMa你介意帮我测试
    map
    和列表理解吗?我目前远离台式机/笔记本电脑..导入字符串和[random.choice(string.ascii_大写+string.ascii_小写)for u in range(37000)]@BigOldTree我的意思是,我不知道OP的数据是否真的是这样,所以我放弃了猜测,只使用一些数字,这既快又脏;)我知道,我用字符得到了不同的结果,所以最快的是带tupleall的lambda,撇开它不谈,这是指向正确方向的最佳答案(即测试不同的方法)不能复制@BigOldTree的结果,使用测试用例大小为370000或37000的随机单字符字符串。但无论如何,基准大多是假的。
    translate 1.5 faster than list comprehensions it seems
    tested in 10000 runs
    
    def remove_chars(string_, word_):
        # 10000 0.112017
        string_ += string_.upper()
        vowels_table = dict.fromkeys(map(ord, string_))
        return word_.translate(vowels_table)
    
    
    def remove_chars2(string_,word_):
        # 10000 0.166002
        return [c for c in word_ if not c in string_]
    
    translate 1.5 faster than list comprehensions it seems
    tested in 10000 runs
    
    def remove_chars(string_, word_):
        # 10000 0.112017
        string_ += string_.upper()
        vowels_table = dict.fromkeys(map(ord, string_))
        return word_.translate(vowels_table)
    
    
    def remove_chars2(string_,word_):
        # 10000 0.166002
        return [c for c in word_ if not c in string_]