从列表中删除所有出现的值?

时间:2009-07-21 03:12:11

标签: python list

在Python中remove()将删除列表中第一次出现的值。

如何从列表中删除所有值,而不对列表进行排序?

这就是我的想法。

>>> x = [1, 2, 3, 4, 2, 2, 3]
>>> def remove_values_from_list(the_list, val):
        while val in the_list:
            the_list.remove(val)
>>> remove_values_from_list(x, 2)
>>> x
[1, 3, 4, 3]

24 个答案:

答案 0 :(得分:407)

功能方法:

<强> 2.x的

>>> x = [1,2,3,2,2,2,3,4]
>>> filter(lambda a: a != 2, x)
[1, 3, 3, 4]

<强> 3.x的

>>> x = [1,2,3,2,2,2,3,4]
>>> list(filter((2).__ne__, x))
[1, 3, 3, 4]

>>> x = [1,2,3,2,2,2,3,4]
>>> list(filter(lambda a: a != 2, x))
[1, 3, 3, 4]

答案 1 :(得分:181)

您可以使用列表理解:

def remove_values_from_list(the_list, val):
   return [value for value in the_list if value != val]

x = [1, 2, 3, 4, 2, 2, 3]
x = remove_values_from_list(x, 2)
print x
# [1, 3, 4, 3]

答案 2 :(得分:92)

如果必须修改原始列表,您仍然可以使用切片分配,同时仍然使用有效的列表推导(或生成器表达式)。

>>> x = [1, 2, 3, 4, 2, 2, 3]
>>> x[:] = (value for value in x if value != 2)
>>> x
[1, 3, 4, 3]

答案 3 :(得分:33)

以更抽象的方式重复第一篇文章的解决方案:

>>> x = [1, 2, 3, 4, 2, 2, 3]
>>> while 2 in x: x.remove(2)
>>> x
[1, 3, 4, 3]

答案 4 :(得分:12)

见简单解决方案

解决方案1:

edit_page.php

这将返回一个包含>>> [i for i in x if i != 2] 所有元素但没有x的列表

解决方案2:

2

答案 5 :(得分:8)

上面的所有答案(除了Martin Andersson)都会创建一个没有所需项目的新列表,而不是从原始列表中删除项目。

>>> import random, timeit
>>> a = list(range(5)) * 1000
>>> random.shuffle(a)

>>> b = a
>>> print(b is a)
True

>>> b = [x for x in b if x != 0]
>>> print(b is a)
False
>>> b.count(0)
0
>>> a.count(0)
1000

>>> b = a
>>> b = filter(lambda a: a != 2, x)
>>> print(b is a)
False

如果您对该列表有其他引用,这可能很重要。

要修改列表,请使用类似这样的方法

>>> def removeall_inplace(x, l):
...     for _ in xrange(l.count(x)):
...         l.remove(x)
...
>>> removeall_inplace(0, b)
>>> b is a
True
>>> a.count(0)
0

就速度而言,我的笔记本电脑上的结果是(所有5000个条目列表中删除了1000个条目)

  • 列表理解 - ~400us
  • 过滤器 - 约900us
  • .remove()循环 - 50ms

所以.remove循环慢了大约100倍........嗯,也许需要一种不同的方法。我发现最快的是使用列表推导,但后来替换原始列表的内容。

>>> def removeall_replace(x, l):
....    t = [y for y in l if y != x]
....    del l[:]
....    l.extend(t)
  • removeall_replace() - 450us

答案 6 :(得分:6)

你可以这样做

while 2 in x:   
    x.remove(2)

答案 7 :(得分:5)

以可读性为代价,我认为这个版本稍快一些,因为它不会强制重新检查列表,因此无论如何都要执行完全相同的工作:

x = [1, 2, 3, 4, 2, 2, 3]
def remove_values_from_list(the_list, val):
    for i in range(the_list.count(val)):
        the_list.remove(val)

remove_values_from_list(x, 2)

print(x)

答案 8 :(得分:3)

删除所有重复的事件并在列表中保留一个:

test = [1, 1, 2, 3]

newlist = list(set(test))

print newlist

[1, 2, 3]

这是我用于Project Euler的函数:

def removeOccurrences(e):
  return list(set(e))

答案 9 :(得分:2)

答案 10 :(得分:2)

针对具有1.000.000元素的列表/数组的Numpy方法和时序:

时序:

In [10]: a.shape
Out[10]: (1000000,)

In [13]: len(lst)
Out[13]: 1000000

In [18]: %timeit a[a != 2]
100 loops, best of 3: 2.94 ms per loop

In [19]: %timeit [x for x in lst if x != 2]
10 loops, best of 3: 79.7 ms per loop

结论:与列表理解方法相比,numpy快了27倍(在我的笔记本上)

PS如果要将常规Python列表lst转换为numpy数组:

arr = np.array(lst)

设定:

import numpy as np
a = np.random.randint(0, 1000, 10**6)

In [10]: a.shape
Out[10]: (1000000,)

In [12]: lst = a.tolist()

In [13]: len(lst)
Out[13]: 1000000

检查:

In [14]: a[a != 2].shape
Out[14]: (998949,)

In [15]: len([x for x in lst if x != 2])
Out[15]: 998949

答案 11 :(得分:1)

for i in range(a.count(' ')):
    a.remove(' ')

我相信更简单。

答案 12 :(得分:1)

第一个解决方案,使用过滤器。
第二种解决方案,使用列表理解。

home_page

答案 13 :(得分:1)

a = [1, 2, 2, 3, 1]
to_remove = 1
a = [i for i in a if i != to_remove]
print(a)
  

也许对我来说不是最Python,但仍然是最简单的哈哈

答案 14 :(得分:1)

从Python列表中删除所有出现的值

lists = [6.9,7,8.9,3,5,4.9,1,2.9,7,9,12.9,10.9,11,7]
def remove_values_from_list():
    for list in lists:
      if(list!=7):
         print(list)
remove_values_from_list()

结果:6.9 8.9 3 5 4.9 1 2.9 9 12.9 10.9 11

可替换地,

lists = [6.9,7,8.9,3,5,4.9,1,2.9,7,9,12.9,10.9,11,7]
def remove_values_from_list(remove):
    for list in lists:
      if(list!=remove):
        print(list)
remove_values_from_list(7)

结果:6.9 8.9 3 5 4.9 1 2.9 9 12.9 10.9 11

答案 15 :(得分:0)

错误:

电机= [&#39; 1&#39;&#39 2&#39;&#39 2&#39;] 对于我在马达:        如果我!=&#39; 2&#39;:        打印(I) 打印(马达)

使用anaconda

答案 16 :(得分:0)

如果您没有内置filter或不想使用多余的空间,并且需要线性解决方案...

def remove_all(A, v):
    k = 0
    n = len(A)
    for i in range(n):
        if A[i] !=  v:
            A[k] = A[i]
            k += 1

    A = A[:k]

答案 17 :(得分:0)

hello =  ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
#chech every item for a match
for item in range(len(hello)-1):
     if hello[item] == ' ': 
#if there is a match, rebuild the list with the list before the item + the list after the item
         hello = hello[:item] + hello [item + 1:]
print hello

['h','e','l','l','o','w','o','r','l','d']

答案 18 :(得分:0)

让我们

>>> x = [1, 2, 3, 4, 2, 2, 3]

之前已经发布的最简单,有效的解决方案是

>>> x[:] = [v for v in x if v != 2]
>>> x
[1, 3, 4, 3]

应该使用较少的内存但速度较慢的另一种可能性是

>>> for i in range(len(x) - 1, -1, -1):
        if x[i] == 2:
            x.pop(i)  # takes time ~ len(x) - i
>>> x
[1, 3, 4, 3]

长度为1000和100000的列表具有10%匹配条目的计时结果:0.16 vs 0.25 ms,23 vs 123 ms。

Timing with length 1000

Timing with length 100000

答案 19 :(得分:0)

我只是做一个清单。我只是一个初学者。稍微高级一点的程序员肯定可以编写这样的函数。

for i in range(len(spam)):
    spam.remove('cat')
    if 'cat' not in spam:
         print('All instances of ' + 'cat ' + 'have been removed')
         break

答案 20 :(得分:0)

没有人发布关于时间和空间复杂性的最佳答案,所以我想我会试一试。这是一个解决方案,它消除了所有出现的特定值,而无需创建新数组,并且时间效率很高。缺点是元素不能保持顺序

时间复杂度:O(n)
额外的空间复杂度:O(1)

def main():
    test_case([1, 2, 3, 4, 2, 2, 3], 2)     # [1, 3, 3, 4]
    test_case([3, 3, 3], 3)                 # []
    test_case([1, 1, 1], 3)                 # [1, 1, 1]


def test_case(test_val, remove_val):
    remove_element_in_place(test_val, remove_val)
    print(test_val)


def remove_element_in_place(my_list, remove_value):
    length_my_list = len(my_list)
    swap_idx = length_my_list - 1

    for idx in range(length_my_list - 1, -1, -1):
        if my_list[idx] == remove_value:
            my_list[idx], my_list[swap_idx] = my_list[swap_idx], my_list[idx]
            swap_idx -= 1

    for pop_idx in range(length_my_list - swap_idx - 1):
        my_list.pop() # O(1) operation


if __name__ == '__main__':
    main()

答案 21 :(得分:0)

我们还可以使用delpop就地删除所有内容:

import random

def remove_values_from_list(lst, target):
    if type(lst) != list:
        return lst

    i = 0
    while i < len(lst):
        if lst[i] == target:
            lst.pop(i)  # length decreased by 1 already
        else:
            i += 1

    return lst

remove_values_from_list(None, 2)
remove_values_from_list([], 2)
remove_values_from_list([1, 2, 3, 4, 2, 2, 3], 2)
lst = remove_values_from_list([random.randrange(0, 10) for x in range(1000000)], 2)
print(len(lst))


现在提高效率

In [21]: %timeit -n1 -r1 x = random.randrange(0,10)
1 loop, best of 1: 43.5 us per loop

In [22]: %timeit -n1 -r1 lst = [random.randrange(0, 10) for x in range(1000000)]
g1 loop, best of 1: 660 ms per loop

In [23]: %timeit -n1 -r1 lst = remove_values_from_list([random.randrange(0, 10) for x in range(1000000)]
    ...: , random.randrange(0,10))
1 loop, best of 1: 11.5 s per loop

In [27]: %timeit -n1 -r1 x = random.randrange(0,10); lst = [a for a in [random.randrange(0, 10) for x in
    ...:  range(1000000)] if x != a]
1 loop, best of 1: 710 ms per loop

正如我们所见,就地版本remove_values_from_list()不需要任何额外的内存,但是运行起来确实需要更多的时间:

  • 11秒用于就地删除值
  • 710毫秒用于列表解析,可在内存中分配新列表

答案 22 :(得分:-1)

关于速度!

import time
s_time = time.time()

print 'start'
a = range(100000000)
del a[:]
print 'finished in %0.2f' % (time.time() - s_time)
# start
# finished in 3.25

s_time = time.time()
print 'start'
a = range(100000000)
a = []
print 'finished in %0.2f' % (time.time() - s_time)
# start
# finished in 2.11

答案 23 :(得分:-2)

p=[2,3,4,4,4]
p.clear()
print(p)
[]

仅限Python 3