关于python:从列表中删除所有出现的值?

Remove all occurrences of a value from a list?

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

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

这就是我想要的。

1
2
3
4
5
6
7
>>> 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]


功能方法:

2、X

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

3、X

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

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


您可以使用列表理解:

1
2
3
4
5
6
7
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]


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

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


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

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


参见简单的解决方案解决方案1:

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

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

解决方案2:

1
>>> while 2 in x : x.remove(2)


以上所有答案(除了马丁·安德森的答案)都创建了一个没有所需项目的新列表,而不是从原始列表中删除项目。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>>> 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

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

要就地修改列表,请使用如下方法

1
2
3
4
5
6
7
8
9
>>> 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倍……嗯,也许需要另一种方法。我发现最快的方法是使用列表理解,然后替换原始列表的内容。

1
2
3
4
>>> def removeall_replace(x, l):
....    t = [y for y in l if y != x]
....    del l[:]
....    l.extend(t)

  • removeall_replace()-450美制


你可以这样做

1
2
while 2 in x:  
    x.remove(2)


以可读性为代价,我认为这个版本稍微快一点,因为它不会强迫while重新检查列表,因此无论如何都要做与remove相同的工作:

1
2
3
4
5
6
7
8
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)


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

1
2
3
4
5
6
7
test = [1, 1, 2, 3]

newlist = list(set(test))

print newlist

[1, 2, 3]

以下是我用于Project Euler的函数:

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


我相信,如果你不关心列表的顺序,如果你确实关心最终的顺序,那么这可能比任何其他方式都快。按这个顺序存储原始索引并使用它。

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


对具有1.000.000元素的列表/数组的numpy方法和计时:

时间安排:

1
2
3
4
5
6
7
8
9
10
11
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数组:

1
arr = np.array(lst)

设置:

1
2
3
4
5
6
7
8
9
10
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

检查:

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

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


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

Perhaps not the most pythonic but still the easiest for me haha


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

我相信简单多了。


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

1
2
3
4
5
6
7
8
#If we want to remove all 2.
ls = [2, 2, 3, 4, 5, 6, 7, 8, 2, 3, 4, 6, 2]

# 1-filter takes two arguments(condition,sequence)
   ls = list(filter(lambda x: x != 2, ls))

# 2-list comprehension
   ls = [x for x in ls if x != 2]


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

1
2
3
4
5
6
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

或者,

1
2
3
4
5
6
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


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

如前所述,最简单有效的解决方案是

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

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

1
2
3
4
5
>>> 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与0.25 ms,23与123 ms。

Timing with length 1000

氧化镁


怎么了:

电机=['1'、'2'、'2']对于电机中的I:如果我!="2":打印(一)打印(电机)

使用Python


如果您没有内置的filter,或者不想使用额外的空间,您需要一个线性解决方案…

1
2
3
4
5
6
7
8
9
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]

1
2
3
4
5
6
7
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']


关于速度!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

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

仅适用于python 3