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

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

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

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

这就是我的想法:

>>> remove_values_from_list([1, 2, 3, 4, 2, 2, 3], 2)
[1, 3, 4, 3]

In Python remove() will remove the first occurrence of value in a list.

How to remove all occurrences of a value from a list?

This is what I have in mind:

>>> remove_values_from_list([1, 2, 3, 4, 2, 2, 3], 2)
[1, 3, 4, 3]

回答 0

功能方法:

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]

Functional approach:

Python 3.x

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

or

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

回答 1

您可以使用列表理解:

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]

You can use a list comprehension:

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

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

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

You can use slice assignment if the original list must be modified, while still using an efficient list comprehension (or generator expression).

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

回答 3

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

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

Repeating the solution of the first post in a more abstract way:

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

回答 4

查看简单的解决方案

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

这将返回具有所有元素的列表x,而不2

See the simple solution

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

This will return a list having all elements of x without 2


回答 5

上面的所有答案(除了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()循环-50毫秒

因此.remove循环要慢100倍左右……..嗯,也许需要另一种方法。我发现最快的方法是使用列表理解,然后替换原始列表的内容。

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

All of the answers above (apart from Martin Andersson’s) create a new list without the desired items, rather than removing the items from the original list.

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

This can be important if you have other references to the list hanging around.

To modify the list in place, use a method like this

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

As far as speed is concerned, results on my laptop are (all on a 5000 entry list with 1000 entries removed)

  • List comprehension – ~400us
  • Filter – ~900us
  • .remove() loop – 50ms

So the .remove loop is about 100x slower…….. Hmmm, maybe a different approach is needed. The fastest I’ve found is using the list comprehension, but then replace the contents of the original list.

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

回答 6

你可以这样做

while 2 in x:   
    x.remove(2)

you can do this

while 2 in x:   
    x.remove(2)

回答 7

我以牺牲可读性为代价,认为此版本稍快一些,因为它不会迫使用户重新检查列表,因此无论如何,要做的删除操作完全相同:

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)

At the cost of readability, I think this version is slightly faster as it doesn’t force the while to reexamine the list, thus doing exactly the same work remove has to do anyway:

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

针对具有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

Numpy approach and timings against a list/array with 1.000.000 elements:

Timings:

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

Conclusion: numpy is 27 times faster (on my notebook) compared to list comprehension approach

PS if you want to convert your regular Python list lst to numpy array:

arr = np.array(lst)

Setup:

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

Check:

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

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

回答 9

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

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

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


回答 10

要删除所有重复的事件并将其留在列表中:

test = [1, 1, 2, 3]

newlist = list(set(test))

print newlist

[1, 2, 3]

这是我用于欧拉计画的功能:

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

To remove all duplicate occurrences and leave one in the list:

test = [1, 1, 2, 3]

newlist = list(set(test))

print newlist

[1, 2, 3]

Here is the function I’ve used for Project Euler:

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

回答 11

我相信,如果您不关心列表顺序,如果您确实关心最终顺序,则可以从原始位置存储索引并以此来求助,这可能比任何其他方式都快。

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

I believe this is probably faster than any other way if you don’t care about the lists order, if you do take care about the final order store the indexes from the original and resort by that.

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

回答 12

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

我相信要简单得多。

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

Much simpler I believe.


回答 13

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

Let

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

The simplest and efficient solution as already posted before is

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

Another possibility which should use less memory but be slower is

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

Timing results for lists of length 1000 and 100000 with 10% matching entries: 0.16 vs 0.25 ms, and 23 vs 123 ms.


回答 14

从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

Remove all occurrences of a value from a Python list

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

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

Alternatively,

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)

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


回答 15

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

If you didn’t have built-in filter or didn’t want to use extra space and you need a linear solution…

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]

回答 16

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

[‘你好,世界’]

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


回答 17

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

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

I just did this for a list. I am just a beginner. A slightly more advanced programmer can surely write a function like this.

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

回答 18

我们也可以使用del或进行就地删除所有内容pop

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毫秒的列表解析时间,可在内存中分配新列表

We can also do in-place remove all using either del or pop:

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


Now for the efficiency:

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

As we see that in-place version remove_values_from_list() does not require any extra memory, but it does take so much more time to run:

  • 11 seconds for inplace remove values
  • 710 milli seconds for list comprehensions, which allocates a new list in memory

回答 19

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

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

No one has posted an optimal answer for time and space complexity, so I thought I would give it a shot. Here is a solution that removes all occurrences of a specific value without creating a new array and at an efficient time complexity. The drawback is that the elements do not maintain order.

Time complexity: O(n)
Additional space complexity: 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()

回答 20

关于速度!

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

About the speed!

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

回答 21

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

仅适用于Python 3

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

Only with Python 3


回答 22

有什么问题:

Motor=['1','2','2']
For i in Motor:
       If i  != '2':
       Print(i)
Print(motor)

使用水蟒

What’s wrong with:

Motor=['1','2','2']
For i in Motor:
       If i  != '2':
       Print(i)
Print(motor)

Using anaconda