简体   繁体   English

有没有一种简单的方法可以按值删除列表元素?

[英]Is there a simple way to delete a list element by value?

I want to remove a value from a list if it exists in the list (which it may not).我想从列表中删除一个值,如果它存在于列表中(它可能不存在)。

a = [1, 2, 3, 4]
b = a.index(6)

del a[b]
print(a)

The above gives the error:以上给出了错误:

ValueError: list.index(x): x not in list

So I have to do this:所以我必须这样做:

a = [1, 2, 3, 4]

try:
    b = a.index(6)
    del a[b]
except:
    pass

print(a)

But is there not a simpler way to do this?但是有没有更简单的方法来做到这一点?

To remove an element's first occurrence in a list, simply use list.remove :要删除列表中第一次出现的元素,只需使用list.remove

>>> a = ['a', 'b', 'c', 'd']
>>> a.remove('b')
>>> print(a)
['a', 'c', 'd']

Mind that it does not remove all occurrences of your element.请注意,它不会删除所有出现的元素。 Use a list comprehension for that.为此使用列表理解。

>>> a = [10, 20, 30, 40, 20, 30, 40, 20, 70, 20]
>>> a = [x for x in a if x != 20]
>>> print(a)
[10, 30, 40, 30, 40, 70]

Usually Python will throw an Exception if you tell it to do something it can't so you'll have to do either:通常 Python 会抛出一个异常,如果你告诉它做一些它不能做的事情,所以你必须这样做:

if c in a:
    a.remove(c)

or:或者:

try:
    a.remove(c)
except ValueError:
    pass

An Exception isn't necessarily a bad thing as long as it's one you're expecting and handle properly.异常不一定是坏事,只要它是您期望的并且正确处理即可。

You can do你可以做

a=[1,2,3,4]
if 6 in a:
    a.remove(6)

but above need to search 6 in list a 2 times, so try except would be faster但上面需要在列表中搜索 6 次 2 次,所以尝试除了会更快

try:
    a.remove(6)
except:
    pass

Consider:考虑:

a = [1,2,2,3,4,5]

To take out all occurrences, you could use the filter function in python.要取出所有出现的情况,您可以使用 python 中的 filter 函数。 For example, it would look like:例如,它看起来像:

a = list(filter(lambda x: x!= 2, a))

So, it would keep all elements of a != 2 .因此,它将保留a != 2所有元素。

To just take out one of the items use要取出其中一件物品,请使用

a.remove(2)

Here's how to do it inplace (without list comprehension):以下是就地操作的方法(没有列表理解):

def remove_all(seq, value):
    pos = 0
    for item in seq:
        if item != value:
           seq[pos] = item
           pos += 1
    del seq[pos:]

If you know what value to delete, here's a simple way (as simple as I can think of, anyway):如果你知道要删除什么值,这里有一个简单的方法(无论如何我能想到的最简单):

a = [0, 1, 1, 0, 1, 2, 1, 3, 1, 4]
while a.count(1) > 0:
    a.remove(1)

You'll get [0, 0, 2, 3, 4]你会得到[0, 0, 2, 3, 4]

As stated by numerous other answers, list.remove() will work, but throw a ValueError if the item wasn't in the list.正如许多其他答案所述, list.remove()将起作用,但如果该项目不在列表中,则会抛出ValueError With python 3.4+, there's an interesting approach to handling this, using the suppress contextmanager :使用 python 3.4+,有一个有趣的方法来处理这个问题,使用抑制上下文管理器

from contextlib import suppress
with suppress(ValueError):
    a.remove('b')

Another possibility is to use a set instead of a list, if a set is applicable in your application.另一种可能性是使用集合而不是列表,如果集合适用于您的应用程序。

IE if your data is not ordered, and does not have duplicates, then IE 如果您的数据未排序,并且没有重复项,则

my_set=set([3,4,2])
my_set.discard(1)

is error-free.没有错误。

Often a list is just a handy container for items that are actually unordered.通常,列表只是一个方便的容器,用于存放实际上无序的项目。 There are questions asking how to remove all occurences of an element from a list.有一些问题询问如何从列表中删除所有出现的元素。 If you don't want dupes in the first place, once again a set is handy.如果您一开始就不想受骗,那么再次设置一套就很方便了。

my_set.add(3)

doesn't change my_set from above.不会从上面改变 my_set 。

In one line:在一行中:

a.remove('b') if 'b' in a else None

sometimes it usefull.有时它很有用。

Even easier:更简单:

if 'b' in a: a.remove('b')

If your elements are distinct, then a simple set difference will do.如果您的元素是不同的,那么简单的集差就可以了。

c = [1,2,3,4,'x',8,6,7,'x',9,'x']
z = list(set(c) - set(['x']))
print z
[1, 2, 3, 4, 6, 7, 8, 9]

This example is fast and will delete all instances of a value from the list:这个例子很快,将从列表中删除一个值的所有实例:

a = [1,2,3,1,2,3,4]
while True:
    try:
        a.remove(3)
    except:
        break
print a
>>> [1, 2, 1, 2, 4]

Finding a value in a list and then deleting that index (if it exists) is easier done by just using list's remove method:在列表中查找值然后删除该索引(如果存在)更容易通过使用列表的 remove 方法完成:

>>> a = [1, 2, 3, 4]
>>> try:
...   a.remove(6)
... except ValueError:
...   pass
... 
>>> print a
[1, 2, 3, 4]
>>> try:
...   a.remove(3)
... except ValueError:
...   pass
... 
>>> print a
[1, 2, 4]

If you do this often, you can wrap it up in a function:如果你经常这样做,你可以把它包装在一个函数中:

def remove_if_exists(L, value):
  try:
    L.remove(value)
  except ValueError:
    pass

Overwrite the list by indexing everything except the elements you wish to remove通过索引除要删除的元素之外的所有内容来覆盖列表

>>> s = [5,4,3,2,1]
>>> s[0:2] + s[3:]
[5, 4, 2, 1]

More generally,更普遍,

>>> s = [5,4,3,2,1]
>>> i = s.index(3)
>>> s[:i] + s[i+1:]
[5, 4, 2, 1]

We can also use .pop:我们也可以使用 .pop:

>>> lst = [23,34,54,45]
>>> remove_element = 23
>>> if remove_element in lst:
...     lst.pop(lst.index(remove_element))
... 
23
>>> lst
[34, 54, 45]
>>> 

With a for loop and a condition:使用 for 循环和条件:

def cleaner(seq, value):    
    temp = []                      
    for number in seq:
        if number != value:
            temp.append(number)
    return temp

And if you want to remove some, but not all:如果你想删除一些,但不是全部:

def cleaner(seq, value, occ):
    temp = []
    for number in seq:
        if number == value and occ:
            occ -= 1
            continue
        else:
            temp.append(number)
    return temp

Many of answers involve creating a new list.许多答案都涉及创建一个新列表。 This involves copying all the data from the old list to the new list (except for the removed items).这涉及将旧列表中的所有数据复制到新列表(删除的项目除外)。 If your list is huge, you may not be able to afford it (or you should not want to).如果你的清单很大,你可能负担不起(或者你不应该想要)。

In these cases, it is much faster to alter the list in place.在这些情况下,就地更改列表要快得多 If you have to remove more than 1 element from the list it can be tricky.如果您必须从列表中删除 1 个以上的元素,这可能会很棘手。 Suppose you loop over the list, and remove an item, then the list changes and a standard for-loop will not take this into account.假设您遍历列表并删除一个项目,然后列表更改并且标准 for 循环不会考虑到这一点。 The result of the loop may not be what you expected.循环的结果可能不是您所期望的。

Example:例子:

a = [0, 1, 2, 3, 4, 5]
for i in a:
    a.remove(i)  # Remove all items
print(a)

Out: [1, 3, 5]

A simple solution is to loop through the list in reverse order.一个简单的解决方案是以相反的顺序循环遍历列表。 In this case you get:在这种情况下,您会得到:

a = [0, 1, 2, 3, 4, 5]
for i in reversed(a):
    a.remove(i)  # Remove all items
print(a)

Out: []

Then, if you need to only remove elements having some specific values, you can simply put an if statement in the loop resulting in:然后,如果您只需要删除具有某些特定值的元素,您可以简单地在循环中放置一个if statement ,结果:

a = [0, 1, 2, 3, 4, 5]
for i in reversed(a):
    if a[i] == 2 or a[i] == 3:  # Remove all items having value 2 or 3.
        a.remove(i)
print(a)

Out: [0, 1, 4, 5]
 list1=[1,2,3,3,4,5,6,1,3,4,5]
 n=int(input('enter  number'))
 while n in list1:
    list1.remove(n)
 print(list1)

Say for example, we want to remove all 1's from x.例如,我们想从 x 中删除所有 1。 This is how I would go about it:这就是我将如何去做:

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

Now, this is a practical use of my method:现在,这是我的方法的实际用途:

def Function(List, Unwanted):
    [List.remove(Unwanted) for Item in range(List.count(Unwanted))]
    return List
x = Function(x, 1)
print(x)

And this is my method in a single line:这是我在一行中的方法:

[x.remove(1) for Item in range(x.count(1))]
print(x)

Both yield this as an output:两者都将其作为输出产生:

[2, 3, 2, 3, 2, 3]

Hope this helps.希望这可以帮助。 PS, pleas note that this was written in version 3.6.2, so you might need to adjust it for older versions. PS,请注意这是在 3.6.2 版本中编写的,因此您可能需要针对旧版本对其进行调整。

When nums is the list and c is the value to be removed:nums是列表并且c是要删除的值时:

To remove the first occurrence of c in the list, just do:要删除列表中第一次出现的c ,只需执行以下操作:

if c in nums:
    nums.remove(c)

To remove all occurrences of c from the list do:要从列表中删除所有出现的c ,请执行以下操作:

while c in nums:
    nums.remove(c)

Adding the exception handling would be the best practice, but I mainly wanted to show how to remove all occurrences of an element from the list.添加异常处理将是最佳实践,但我主要想展示如何从列表中删除所有出现的元素。

arr = [1, 1, 3, 4, 5, 2, 4, 3]

# to remove first occurence of that element, suppose 3 in this example
arr.remove(3)

# to remove all occurences of that element, again suppose 3
# use something called list comprehension
new_arr = [element for element in arr if element!=3]

# if you want to delete a position use "pop" function, suppose 
# position 4 
# the pop function also returns a value
removed_element = arr.pop(4)

# u can also use "del" to delete a position
del arr[4]

This removes all instances of "-v" from the array sys.argv , and does not complain if no instances were found:这将从数组sys.argv删除所有"-v"实例,如果没有找到实例,则不会抱怨:

while "-v" in sys.argv:
    sys.argv.remove('-v')

You can see the code in action, in a file called speechToText.py :您可以在名为speechToText.py的文件中看到正在运行的代码:

$ python speechToText.py -v
['speechToText.py']

$ python speechToText.py -x
['speechToText.py', '-x']

$ python speechToText.py -v -v
['speechToText.py']

$ python speechToText.py -v -v -x
['speechToText.py', '-x']

Maybe your solutions works with ints, but It Doesnt work for me with dictionarys.也许您的解决方案适用于整数,但它不适用于我的字典。

In one hand, remove() has not worked for me.一方面, remove() 对我不起作用。 But maybe it works with basic Types.但也许它适用于基本类型。 I guess the code bellow is also the way to remove items from objects list.我猜下面的代码也是从对象列表中删除项目的方法。

In the other hand, 'del' has not worked properly either.另一方面,“del”也没有正常工作。 In my case, using python 3.6: when I try to delete an element from a list in a 'for' bucle with 'del' command, python changes the index in the process and bucle stops prematurely before time.就我而言,使用 python 3.6:当我尝试使用 'del' 命令从 'for' bucle 中的列表中删除一个元素时,python 更改了进程中的索引,并且 bucle 在时间之前过早停止。 It only works if You delete element by element in reversed order.它仅在您以相反的顺序逐个删除元素时才有效。 In this way you dont change the pending elements array index when you are going through it通过这种方式,您在浏览时不会更改挂起的元素数组索引

Then, Im used:然后,我使用了:

c = len(list)-1
for element in (reversed(list)):
    if condition(element):
        del list[c]
    c -= 1
print(list)

where 'list' is like [{'key1':value1'},{'key2':value2}, {'key3':value3}, ...]其中 'list' 就像 [{'key1':value1'},{'key2':value2}, {'key3':value3}, ...]

Also You can do more pythonic using enumerate:你也可以使用 enumerate 做更多的 Pythonic:

for i, element in enumerate(reversed(list)):
    if condition(element):
        del list[(i+1)*-1]
print(list)

Benchmark of some of the simplest method:一些最简单方法的基准测试:

import random
from copy import copy
sample = random.sample(range(100000), 10000)
remove = random.sample(range(100000), 1000)

%%timeit
sample1 = copy(sample)
remove1 = copy(remove)

for i in reversed(sample1):
    if i in remove1:
        sample1.remove(i)
# 271 ms ± 16 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# remove all instances

%%timeit
sample1 = copy(sample)
remove1 = copy(remove)

filtered = list(filter(lambda x: x not in remove1, sample1))
# 280 ms ± 18.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# remove all instances

%%timeit
sample1 = copy(sample)
remove1 = copy(remove) 

filtered = [ele for ele in sample1 if ele not in remove1]
# 293 ms ± 72.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# remove all instances

%%timeit
sample1 = copy(sample)
remove1 = copy(remove) 

for val in remove1:
    if val in sample1:
        sample1.remove(val)
# 558 ms ± 40.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# only remove first occurrence

%%timeit
sample1 = copy(sample)
remove1 = copy(remove) 

for val in remove1:
    try:
        sample1.remove(val)
    except:
        pass
# 609 ms ± 11.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# only remove first occurrence

This is a less efficient solution, but it still works:这是一个效率较低的解决方案,但它仍然有效:

a = [ ] // that is your list a = [ ] // 那是你的列表

b // element(s) you need to delete b // 你需要删除的元素

counter = a.count(b)

while counter > 0:
    if b in a:
       a.remove(b)
       counter -= 1

print(a)

this is my answer, just use while and for这是我的答案,只需使用whilefor

def remove_all(data, value):
    i = j = 0
    while j < len(data):
        if data[j] == value:
            j += 1
            continue
        data[i] = data[j]
        i += 1
        j += 1
    for x in range(j - i):
        data.pop()

syntax: lst.remove(x) 语法:lst.remove(x)

lst = ['one', 'two', 'three', 'four', 'two']

lst.remove('two') #it will remove first occurence of 'two' in a given list

del lst[2] #delete item by index value

print(lst)

Yes. 是。 This is what I found to be most useful: 这是我发现最有用的:

import sys

a = [1, 2, 3, 4]

y = 0

if y < 1:
      a.remove(1)
      print len(a)
else:
    sys.exit()

Now .remove() only takes one argument, so you can only remove one integer from your list. 现在.remove()仅接受一个参数,因此您只能从列表中删除一个整数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM