从另一个列表中删除一个列表中的所有值? [重复]

时间:2022-01-25 00:33:21

This question already has an answer here:

这个问题在这里已有答案:

I am looking for a way to remove all values within a list from another list.

我正在寻找一种方法来从另一个列表中删除列表中的所有值。

Something like this:

像这样的东西:

a = range(1,10)  
a.remove([2,3,7])  
print a  
a = [1,4,5,6,8,9]  

7 个解决方案

#1


97  

>>> a = range(1, 10)
>>> [x for x in a if x not in [2, 3, 7]]
[1, 4, 5, 6, 8, 9]

#2


32  

If you don't have repeated values, you could use set difference.

如果您没有重复值,则可以使用set difference。

x = set(range(10))
y = x - set([2, 3, 7])
# y = set([0, 1, 4, 5, 6, 8, 9])

and then convert back to list, if needed.

然后转换回列表,如果需要的话。

#3


17  

I was looking for fast way to do the subject, so I made some experiments with suggested ways. And I was surprised by results, so I want to share it with you.

我正在寻找快速的方法来完成这个主题,所以我用建议的方法做了一些实验。我对结果感到惊讶,所以我想和你分享。

Experiments were done using pythonbenchmark tool and with

实验是使用pythonbenchmark工具完成的

a = range(1,50000) # Source list
b = range(1,15000) # Items to remove

Results:

结果:

 def comprehension(a, b):
     return [x for x in a if x not in b]

5 tries, average time 12.8 sec

5次尝试,平均时间12.8秒

def filter_function(a, b):
    return filter(lambda x: x not in b, a)

5 tries, average time 12.6 sec

5次尝试,平均时间12.6秒

def modification(a,b):
    for x in b:
        try:
            a.remove(x)
        except ValueError:
            pass
    return a

5 tries, average time 0.27 sec

5次尝试,平均时间0.27秒

def set_approach(a,b):
    return list(set(a)-set(b))

5 tries, average time 0.0057 sec

5次尝试,平均时间0.0057秒

Also I made another measurement with bigger inputs size for the last two functions

此外,我还为最后两个函数使用更大的输入大小进行了另一次测量

a = range(1,500000)
b = range(1,100000)

And the results:

结果如下:

For modification (remove method) - average time is 252 seconds For set approach - average time is 0.75 seconds

对于修改(删除方法) - 平均时间为252秒对于设置方法 - 平均时间为0.75秒

So you can see that approach with sets is significantly faster than others. Yes, it doesn't keep similar items, but if you don't need it - it's for you. And there is almost no difference between list comprehension and using filter function. Using 'remove' is ~50 times faster, but it modifies source list. And the best choice is using sets - it's more than 1000 times faster than list comprehension!

因此,您可以看到使用集合的方法明显快于其他方法。是的,它没有保留类似的物品,但如果你不需要它 - 它适合你。列表理解与使用过滤功能之间几乎没有区别。使用'remove'的速度要快50倍,但它会修改源列表。最好的选择是使用套装 - 它比列表理解快1000倍!

#4


11  

a = range(1,10)
itemsToRemove = set([2, 3, 7])
b = filter(lambda x: x not in itemsToRemove, a)

or

要么

b = [x for x in a if x not in itemsToRemove]

Don't create the set inside the lambda or inside the comprehension. If you do, it'll be recreated on every iteration, defeating the point of using a set at all.

不要在lambda内部或在理解内部创建集合。如果你这样做,它将在每次迭代时重新创建,完全不使用集合。

#5


5  

Others have suggested ways to make newlist after filtering e.g.

其他人建议在过滤后制作新列表的方法,例如

newl = [x for x in l if x not in [2,3,7]]

or

要么

newl = filter(lambda x: x not in [2,3,7], l) 

but from your question it looks you want in-place modification for that you can do this, this will also be much much faster if original list is long and items to be removed less

但是根据你的问题看起来你想要就地修改你可以做到这一点,如果原始列表很长并且要删除的项目也会快得多

l = range(1,10)
for o in set([2,3,7,11]):
    try:
        l.remove(o)
    except ValueError:
        pass

print l

output: [1, 4, 5, 6, 8, 9]

输出:[1,4,5,6,8,9]

I am checking for ValueError exception so it works even if items are not in orginal list.

我正在检查ValueError异常,因此即使项目不在原始列表中也能正常工作。

Also if you do not need in-place modification solution by S.Mark is simpler.

此外,如果您不需要S.Mark的就地修改解决方案更简单。

#6


5  

The simplest way is

最简单的方法是

>>> a = range(1, 10)
>>> for x in [2, 3, 7]:
...  a.remove(x)
... 
>>> a
[1, 4, 5, 6, 8, 9]

One possible problem here is that each time you call remove(), all the items are shuffled down the list to fill the hole. So if a grows very large this will end up being quite slow.

这里可能存在的一个问题是,每次调用remove()时,所有项都会在列表中随机移动以填充漏洞。因此,如果增长非常大,这将最终变得非常缓慢。

This way builds a brand new list. The advantage is that we avoid all the shuffling of the first approach

这种方式构建了一个全新的列表。优点是我们避免了第一种方法的所有改组

>>> removeset = set([2, 3, 7])
>>> a = [x for x in a if x not in removeset]

If you want to modify a in place, just one small change is required

如果要在适当的位置进行修改,只需进行一处小改动即可

>>> removeset = set([2, 3, 7])
>>> a[:] = [x for x in a if x not in removeset]

#7


4  

>>> a=range(1,10)
>>> for i in [2,3,7]: a.remove(i)
...
>>> a
[1, 4, 5, 6, 8, 9]

>>> a=range(1,10)
>>> b=map(a.remove,[2,3,7])
>>> a
[1, 4, 5, 6, 8, 9]

#1


97  

>>> a = range(1, 10)
>>> [x for x in a if x not in [2, 3, 7]]
[1, 4, 5, 6, 8, 9]

#2


32  

If you don't have repeated values, you could use set difference.

如果您没有重复值,则可以使用set difference。

x = set(range(10))
y = x - set([2, 3, 7])
# y = set([0, 1, 4, 5, 6, 8, 9])

and then convert back to list, if needed.

然后转换回列表,如果需要的话。

#3


17  

I was looking for fast way to do the subject, so I made some experiments with suggested ways. And I was surprised by results, so I want to share it with you.

我正在寻找快速的方法来完成这个主题,所以我用建议的方法做了一些实验。我对结果感到惊讶,所以我想和你分享。

Experiments were done using pythonbenchmark tool and with

实验是使用pythonbenchmark工具完成的

a = range(1,50000) # Source list
b = range(1,15000) # Items to remove

Results:

结果:

 def comprehension(a, b):
     return [x for x in a if x not in b]

5 tries, average time 12.8 sec

5次尝试,平均时间12.8秒

def filter_function(a, b):
    return filter(lambda x: x not in b, a)

5 tries, average time 12.6 sec

5次尝试,平均时间12.6秒

def modification(a,b):
    for x in b:
        try:
            a.remove(x)
        except ValueError:
            pass
    return a

5 tries, average time 0.27 sec

5次尝试,平均时间0.27秒

def set_approach(a,b):
    return list(set(a)-set(b))

5 tries, average time 0.0057 sec

5次尝试,平均时间0.0057秒

Also I made another measurement with bigger inputs size for the last two functions

此外,我还为最后两个函数使用更大的输入大小进行了另一次测量

a = range(1,500000)
b = range(1,100000)

And the results:

结果如下:

For modification (remove method) - average time is 252 seconds For set approach - average time is 0.75 seconds

对于修改(删除方法) - 平均时间为252秒对于设置方法 - 平均时间为0.75秒

So you can see that approach with sets is significantly faster than others. Yes, it doesn't keep similar items, but if you don't need it - it's for you. And there is almost no difference between list comprehension and using filter function. Using 'remove' is ~50 times faster, but it modifies source list. And the best choice is using sets - it's more than 1000 times faster than list comprehension!

因此,您可以看到使用集合的方法明显快于其他方法。是的,它没有保留类似的物品,但如果你不需要它 - 它适合你。列表理解与使用过滤功能之间几乎没有区别。使用'remove'的速度要快50倍,但它会修改源列表。最好的选择是使用套装 - 它比列表理解快1000倍!

#4


11  

a = range(1,10)
itemsToRemove = set([2, 3, 7])
b = filter(lambda x: x not in itemsToRemove, a)

or

要么

b = [x for x in a if x not in itemsToRemove]

Don't create the set inside the lambda or inside the comprehension. If you do, it'll be recreated on every iteration, defeating the point of using a set at all.

不要在lambda内部或在理解内部创建集合。如果你这样做,它将在每次迭代时重新创建,完全不使用集合。

#5


5  

Others have suggested ways to make newlist after filtering e.g.

其他人建议在过滤后制作新列表的方法,例如

newl = [x for x in l if x not in [2,3,7]]

or

要么

newl = filter(lambda x: x not in [2,3,7], l) 

but from your question it looks you want in-place modification for that you can do this, this will also be much much faster if original list is long and items to be removed less

但是根据你的问题看起来你想要就地修改你可以做到这一点,如果原始列表很长并且要删除的项目也会快得多

l = range(1,10)
for o in set([2,3,7,11]):
    try:
        l.remove(o)
    except ValueError:
        pass

print l

output: [1, 4, 5, 6, 8, 9]

输出:[1,4,5,6,8,9]

I am checking for ValueError exception so it works even if items are not in orginal list.

我正在检查ValueError异常,因此即使项目不在原始列表中也能正常工作。

Also if you do not need in-place modification solution by S.Mark is simpler.

此外,如果您不需要S.Mark的就地修改解决方案更简单。

#6


5  

The simplest way is

最简单的方法是

>>> a = range(1, 10)
>>> for x in [2, 3, 7]:
...  a.remove(x)
... 
>>> a
[1, 4, 5, 6, 8, 9]

One possible problem here is that each time you call remove(), all the items are shuffled down the list to fill the hole. So if a grows very large this will end up being quite slow.

这里可能存在的一个问题是,每次调用remove()时,所有项都会在列表中随机移动以填充漏洞。因此,如果增长非常大,这将最终变得非常缓慢。

This way builds a brand new list. The advantage is that we avoid all the shuffling of the first approach

这种方式构建了一个全新的列表。优点是我们避免了第一种方法的所有改组

>>> removeset = set([2, 3, 7])
>>> a = [x for x in a if x not in removeset]

If you want to modify a in place, just one small change is required

如果要在适当的位置进行修改,只需进行一处小改动即可

>>> removeset = set([2, 3, 7])
>>> a[:] = [x for x in a if x not in removeset]

#7


4  

>>> a=range(1,10)
>>> for i in [2,3,7]: a.remove(i)
...
>>> a
[1, 4, 5, 6, 8, 9]

>>> a=range(1,10)
>>> b=map(a.remove,[2,3,7])
>>> a
[1, 4, 5, 6, 8, 9]