只需一条语句即可从 Python 列表中删除多项
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36268749/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Remove multiple items from a Python list in just one statement
提问by RandomCoder
In python, I know how to remove items from a list.
在 python 中,我知道如何从列表中删除项目。
item_list = ['item', 5, 'foo', 3.14, True]
item_list.remove('item')
item_list.remove(5)
This above code removes the values 5 and 'item' from item_list. But when there is a lot of stuff to remove, I have to write many lines of
上面的代码从 item_list 中删除了值 5 和 'item'。但是当有很多东西要删除时,我必须写很多行
item_list.remove("something_to_remove")
If I know the index of what I am removing, I use:
如果我知道要删除的内容的索引,我会使用:
del item_list[x]
where x is the index of the item I want to remove.
其中 x 是我要删除的项目的索引。
If I know the index of all of the numbers that I want to remove, I'll use some sort of loop to del
the items at the indices.
如果我知道要删除的所有数字的索引,我将对del
索引处的项目使用某种循环。
But what if I don't know the indices of the items I want to remove?
但是,如果我不知道要删除的项目的索引怎么办?
I tried item_list.remove('item', 'foo')
, but I got an error saying that remove
only takes one argument.
我试过了item_list.remove('item', 'foo')
,但我收到一个错误,说remove
只需要一个参数。
Is there a way to remove multiple items from a list in a single statement?
有没有办法在单个语句中从列表中删除多个项目?
P.S. I've used del
and remove
. Can someone explain the difference between these two, or are they the same?
PS我用过del
和remove
。有人可以解释这两者之间的区别,还是它们相同?
Thanks
谢谢
回答by aluriak
In Python, create a new object is often better than modify an existing one:
在 Python 中,创建新对象通常比修改现有对象更好:
item_list = ['item', 5, 'foo', 3.14, True]
item_list = [e for e in item_list if e not in ('item', 5)]
Which is equivalent to:
这相当于:
item_list = ['item', 5, 'foo', 3.14, True]
new_list = []
for e in item_list:
if e not in ('item', 5):
new_list.append(e)
item_list = new_list
In case of a big list of filtered out values (here, ('item', 5)
is a small set of element), use a set
can lead to performance improvement, as the in
operation is in O(1) :
如果过滤掉的值列表很大(这里('item', 5)
是一小组元素),使用 aset
可以提高性能,因为in
操作在 O(1) 中:
item_list = [e for e in item_list if e not in {'item', 5}]
Note that, as explained in comments and suggested here, the following could save even more time, avoiding the set to be built at each loop:
请注意,正如评论中所解释和建议的here,以下可以节省更多时间,避免在每个循环中构建集合:
unwanted = {'item', 5}
item_list = [e for e in item_list if e not in unwanted]
A bloom filteris also a good solution if memory is not cheap.
一个布隆过滤器也是一个不错的解决方案,如果内存是不便宜。
回答by Aakash Goel
item_list = ['item', 5, 'foo', 3.14, True]
list_to_remove=['item', 5, 'foo']
final list after removing should be as follow
删除后的最终列表应如下
final_list=[3.14, True]
Single Line Code
单行代码
final_list= list(set(item_list).difference(set(list_to_remove)))
output would be as follow
输出如下
final_list=[3.14, True]
回答by Anwarvic
I don't know why everyone forgot to mention the amazing capability of set
s in python. You can simply cast your list into a set and then remove whatever you want to remove in a simple expression like so:
不知道为什么大家忘了提set
python中s的惊人能力。您可以简单地将您的列表转换为一个集合,然后在一个简单的表达式中删除您想要删除的任何内容,如下所示:
>>> item_list = ['item', 5, 'foo', 3.14, True]
>>> item_list = set(item_list) - {'item', 5}
>>> item_list
{True, 3.14, 'foo'}
>>> # you can cast it again in a list-from like so
>>> item_list = list(item_list)
>>> item_list
[True, 3.14, 'foo']
回答by Darkonaut
I'm reposting my answer from herebecause I saw it also fits in here. It allows removing multiple values or removing only duplicates of these values and returns either a new list or modifies the given list in place.
我从这里重新发布我的答案,因为我看到它也适合这里。它允许删除多个值或仅删除这些值的重复项,并返回一个新列表或就地修改给定列表。
def removed(items, original_list, only_duplicates=False, inplace=False):
"""By default removes given items from original_list and returns
a new list. Optionally only removes duplicates of `items` or modifies
given list in place.
"""
if not hasattr(items, '__iter__') or isinstance(items, str):
items = [items]
if only_duplicates:
result = []
for item in original_list:
if item not in items or item not in result:
result.append(item)
else:
result = [item for item in original_list if item not in items]
if inplace:
original_list[:] = result
else:
return result
Docstring extension:
文档字符串扩展:
"""
Examples:
---------
>>>li1 = [1, 2, 3, 4, 4, 5, 5]
>>>removed(4, li1)
[1, 2, 3, 5, 5]
>>>removed((4,5), li1)
[1, 2, 3]
>>>removed((4,5), li1, only_duplicates=True)
[1, 2, 3, 4, 5]
# remove all duplicates by passing original_list also to `items`.:
>>>removed(li1, li1, only_duplicates=True)
[1, 2, 3, 4, 5]
# inplace:
>>>removed((4,5), li1, only_duplicates=True, inplace=True)
>>>li1
[1, 2, 3, 4, 5]
>>>li2 =['abc', 'def', 'def', 'ghi', 'ghi']
>>>removed(('def', 'ghi'), li2, only_duplicates=True, inplace=True)
>>>li2
['abc', 'def', 'ghi']
"""
You should be clear about what you really want to do, modify an existing list, or make a new list with the specific items missing. It's important to make that distinction in case you have a second reference pointing to the existing list. If you have, for example...
您应该清楚自己真正想要做什么,修改现有列表,或者创建一个缺少特定项目的新列表。如果您有指向现有列表的第二个引用,则进行区分很重要。例如,如果您有...
li1 = [1, 2, 3, 4, 4, 5, 5]
li2 = li1
# then rebind li1 to the new list without the value 4
li1 = removed(4, li1)
# you end up with two separate lists where li2 is still pointing to the
# original
li2
# [1, 2, 3, 4, 4, 5, 5]
li1
# [1, 2, 3, 5, 5]
This may or may not be the behaviour you want.
这可能是也可能不是您想要的行为。
回答by aless80
But what if I don't know the indices of the items I want to remove?
但是,如果我不知道要删除的项目的索引怎么办?
I do not exactly understand why you do not like .remove but to get the first index corresponding to a value use .index(value):
我不完全明白为什么你不喜欢 .remove 而是获取与值对应的第一个索引使用 .index(value):
ind=item_list.index('item')
then remove the corresponding value:
然后删除相应的值:
del item_list.pop[ind]
.index(value) gets the first occurrence of value, and .remove(value) removes the first occurrence of value
.index(value) 获取第一次出现的 value, .remove(value) 移除第一次出现的 value
回答by Vlad Bezden
You can use filterfalsefunction from itertoolsmodule
您可以使用itertools模块中的filterfalse函数
Example
例子
import random
from itertools import filterfalse
random.seed(42)
data = [random.randrange(5) for _ in range(10)]
clean = [*filterfalse(lambda i: i == 0, data)]
print(f"Remove 0s\n{data=}\n{clean=}\n")
clean = [*filterfalse(lambda i: i in (0, 1), data)]
print(f"Remove 0s and 1s\n{data=}\n{clean=}")
Output:
输出:
Remove 0s
data=[0, 0, 2, 1, 1, 1, 0, 4, 0, 4]
clean=[2, 1, 1, 1, 4, 4]
Remove 0s and 1s
data=[0, 0, 2, 1, 1, 1, 0, 4, 0, 4]
clean=[2, 4, 4]
回答by Krishna Singhal
You Can use this -
你可以用这个 -
Suppose we have a list, l = [1,2,3,4,5]
假设我们有一个列表, l = [1,2,3,4,5]
We want to delete last two items in a single statement
我们想删除单个语句中的最后两项
del l[3:]
We have output:
我们有输出:
l = [1,2,3]
l = [1,2,3]
Keep it Simple
把事情简单化