简体   繁体   中英

What's the simplest way to subtract all elements of one list from another list?

Given list1 = [1,2,2,3] , list2 = [1,2] , what's the simplest way to subtract all element of list2 from list1 to get list list3 = [2,3]

It seems sum work well for two lists but subtraction doesn't.

To clarify: Order doesn't matter. L2 is a subset of L1. Duplicates need to be kept. Therefore can't use set .

>>> [1,2,2,3]+[1,2,3]
[1, 2, 2, 3, 1, 2, 3]

>>> [1,2,2,3]-[1,2]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for -: 'list' and 'list'

You can try using remove :

list1 = [1,2,2,2,3]
list2 = [1,2,2]

[list1.remove(i) for i in list2] 
list1

Output:

[2, 3]

Update without list comprehension, using standard for loops.

for i in list2:
    list1.remove(i)
list1

Output:

[2, 3]

You could use collections.Counter and a list comprehension :

from collections import Counter

list1 = [1, 2, 2, 2, 3]
list2 = [1, 2, 2]

counts = Counter(list2)
result = [l for l in list1 if counts.get(l, 0) == 0 or counts.subtract((l,))]

print(result)

Output

[2, 3]

The list comprehension is equivalent to:

result = []
for l in list1:
    if counts.get(l, 0) == 0 or counts.subtract((l,)):
        result.append(l)

The tricky part here is the statement counts.get(l, 0) == 0 or counts.subtract((l,)) . The counts.subtract((l,)) means subtract 1 from the count of l and the return value of the expression is None , the fact that None is a boolean-like value (that evals to False ) allows to use it a single or expression. So the above or will only be True when counts.get(l, 0) == 0 .

This is how I would do it:

def remove_elems(l1, l2):
    removals = set(l2)
    result = []
    for elem in l1:
        if elem in removals:
            removals.remove(elem)
        else:
            result.append(elem)
    return result

l1 = [1,2,2,3]
l2 = [1,2]

print(remove_elems(l1, l2))  # -> [2, 3]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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