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

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

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

这就是我的想法:

>>> remove_values_from_list([1, 2, 3, 4, 2, 2, 3], 2)
[1, 3, 4, 3]
755651 次浏览

你可以使用列表推导式:

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]

功能的方法:

Python 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]

Python 2. x

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

如果必须修改原始列表,则可以使用切片赋值,同时仍然使用有效的列表理解式(或生成器表达式)。

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

如果你不关心列表的顺序,如果你关心最终的顺序,我相信这可能比其他任何方法都快。

category_ids.sort()
ones_last_index = category_ids.count('1')
del category_ids[0:ones_last_index]

以可读性为代价,我认为这个版本稍微快一点,因为它不强迫while重新检查列表,因此做完全相同的工作删除必须做的事情:

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)

删除所有重复的出现,并在列表中保留一个:

test = [1, 1, 2, 3]


newlist = list(set(test))


print newlist


[1, 2, 3]

下面是我在Project Euler中使用的函数:

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

上面所有的答案(除了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

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

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

只有在Python 3中

从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

Numpy方法和对包含1.000.000个元素的列表/数组的计时:

计时:

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

更好的解决方案与列表理解

x = [ i for i in x if i!=2 ]
for i in range(a.count(' ')):
a.remove(' ')

我相信要简单得多。

参见简单的解决方案

>>> [i for i in x if i != 2]

这将返回一个包含所有x元素的列表,但没有2

关于速度!

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

有什么问题:

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

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

如果你没有内置的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]
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 ')

>>> 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

我只是做了一个列表。我只是个初学者。稍微高级一点的程序员当然可以写出这样的函数。

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

没有人给出时间和空间复杂性的最佳答案,所以我想试试。下面是一种解决方案,它可以在不创建新数组的情况下删除所有特定值的出现,并且具有有效的时间复杂度。缺点是元素不维护订单

时间复杂度: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()

我们也可以使用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毫秒用于列表推导,它在内存中分配一个新列表

很多答案都很好。如果你是python初学者,这里有一个简单的方法,以防你肯定想使用remove()方法。

rawlist = [8, 1, 8, 5, 8, 2, 8, 9, 8, 4]


ele_remove = 8


for el in rawlist:
if el == ele_remove:
rawlist.remove(ele_remove)

对于太大的列表,它可能会慢一些。

如果你的列表只包含一个元素的副本,例如list_a=[0,0,0,0,0,0,1,3,4,6,7],下面的代码将会很有帮助:

list_a=[0,0,0,0,0,0,1,3,4,6,7]
def remove_element(element,the_list):
the_list=list(set(the_list))
the_list.remove(element)
return the_list


list_a=remove_element(element=0,the_list=list_a)
print(list_a)

a=list(set(i for i in list_a if i!=2))
a.remove(2)

基本思想是sets不允许重复,所以首先我将列表转换为set(这样可以去掉重复的部分),然后使用.remove()函数删除元素的第一个实例(现在我们每个项目只有一个实例)。


但如果你有多个元素的副本,下面的方法会有帮助:

  1. 列表理解
list_a=[1, 2, 3, 4, 2, 2, 3]
remove_element=lambda element,the_list:[i for i in the_list if i!=element]
print(remove_element(element=2,the_list=list_a))
  1. 过滤器
list_a=[1, 2, 3, 4, 2, 2, 3]
a=list(filter(lambda a: a != 2, list_a))
print(a)
  1. While循环
list_a=[1, 2, 3, 4, 2, 2, 3]
def remove_element(element,the_list):
while element in the_list:the_list.remove(element)
return the_list
print(remove_element(2,list_a))
  1. for循环(与列表推导式相同)
list_a=[1, 2, 3, 4, 2, 2, 3]
a=[]
for i in list_a:
if i!=2:
a.append(i)
print(a)