在可能出现重复值的 python 中从另一个列表中减去一个列表
Subtracting one list from another in python where duplicate values may occur
我想从另一个数组中删除一个数组的内容。
array_2 = ['one' , "two" , "one", "three", "four"]
array_1 = ['one', "two"]
我第一个想到的是使用列表comprehensions
array_3 = [x for x in array_2 if x not in array_1]
但是这会删除重复项
结果:['three', 'four']
我只想从数组中删除 "one"
一次,因为我正在寻找列表减法。所以我希望结果是:['one', 'three', 'four']
.
实现此目的的良好 pythonic 方法是什么?
尝试 Counter
来自 collections
:
from collections import Counter
array_2 = ['one' , "two" , "one", "three", "four"]
array_1 = ['one', "two"]
list((Counter(array_2) - Counter(array_1)).elements())
输出
['one', 'three', 'four']
您可以使用列表的remove
方法:
array_2 = ['one' , "two" , "one", "three", "four"]
array_1 = ['one', "two"]
# copy list
array_3 = array_2[:]
for element in array_1:
try:
array_3.remove(element)
except ValueError:
pass
print(array_3)
# ['one', 'three', 'four']
Counter
对象非常适合这个。
In [1]: from collections import Counter
In [2]: array_2 = ['one' , "two" , "one", "three", "four"]
In [3]: array_1 = ['one', "two"]
In [4]: a2 = Counter(array_2)
In [5]: a1 = Counter(array_1)
In [6]: a2 - a1
Out[6]: Counter({'one': 1, 'three': 1, 'four': 1})
如果您想要一个列表,您可以使用以下方法展平 Counter
:
In [7]: list((a2-a1).elements())
Out[7]: ['one', 'three', 'four']
结合使用 map
函数和 lambda
可以解决您的任务:
map(lambda x: array_2.remove(x) if x in array_2 else None, array_1)
这将直接更改 array_2
,结果将是:
print(array_2)
# ['one', 'three', 'four']
我就把上面已经给出的优秀解法收集起来
如果您关心保持 array_2
中元素的原始顺序,那么我认为您必须使用 remove
:
array_1 = ['one', 'two']
array_2 = ['one', 'two', 'one', 'three', 'four']
array_3 = list(array_2)
for x in array_1:
try:
array_3.remove(x)
except ValueError:
pass
print(array_3)
如果元素的最终顺序是什么并不重要,那么使用 Counter
会更有效率,因为它只在两个列表上循环一次:
from collections import Counter
array_1 = ['one', 'two']
array_2 = ['one', 'two', 'one', 'three', 'four']
array_3 = list((Counter(array_2) - Counter(array_1)).elements())
print(array_3)
我想从另一个数组中删除一个数组的内容。
array_2 = ['one' , "two" , "one", "three", "four"]
array_1 = ['one', "two"]
我第一个想到的是使用列表comprehensions
array_3 = [x for x in array_2 if x not in array_1]
但是这会删除重复项
结果:['three', 'four']
我只想从数组中删除 "one"
一次,因为我正在寻找列表减法。所以我希望结果是:['one', 'three', 'four']
.
实现此目的的良好 pythonic 方法是什么?
尝试 Counter
来自 collections
:
from collections import Counter
array_2 = ['one' , "two" , "one", "three", "four"]
array_1 = ['one', "two"]
list((Counter(array_2) - Counter(array_1)).elements())
输出
['one', 'three', 'four']
您可以使用列表的remove
方法:
array_2 = ['one' , "two" , "one", "three", "four"]
array_1 = ['one', "two"]
# copy list
array_3 = array_2[:]
for element in array_1:
try:
array_3.remove(element)
except ValueError:
pass
print(array_3)
# ['one', 'three', 'four']
Counter
对象非常适合这个。
In [1]: from collections import Counter
In [2]: array_2 = ['one' , "two" , "one", "three", "four"]
In [3]: array_1 = ['one', "two"]
In [4]: a2 = Counter(array_2)
In [5]: a1 = Counter(array_1)
In [6]: a2 - a1
Out[6]: Counter({'one': 1, 'three': 1, 'four': 1})
如果您想要一个列表,您可以使用以下方法展平 Counter
:
In [7]: list((a2-a1).elements())
Out[7]: ['one', 'three', 'four']
结合使用 map
函数和 lambda
可以解决您的任务:
map(lambda x: array_2.remove(x) if x in array_2 else None, array_1)
这将直接更改 array_2
,结果将是:
print(array_2)
# ['one', 'three', 'four']
我就把上面已经给出的优秀解法收集起来
如果您关心保持 array_2
中元素的原始顺序,那么我认为您必须使用 remove
:
array_1 = ['one', 'two']
array_2 = ['one', 'two', 'one', 'three', 'four']
array_3 = list(array_2)
for x in array_1:
try:
array_3.remove(x)
except ValueError:
pass
print(array_3)
如果元素的最终顺序是什么并不重要,那么使用 Counter
会更有效率,因为它只在两个列表上循环一次:
from collections import Counter
array_1 = ['one', 'two']
array_2 = ['one', 'two', 'one', 'three', 'four']
array_3 = list((Counter(array_2) - Counter(array_1)).elements())
print(array_3)