简体   繁体   中英

Python - alternative to list.remove(x)?

I wish to compare two lists. Generally this is not a problem as I usually use a nested for loop and append the intersection to a new list. In this case, I need to delete the intersection of A and B from A.

 A = [['ab', 'cd', 'ef', '0', '567'], ['ghy5'], ['pop', 'eye']]

 B = [['ab'], ['hi'], ['op'], ['ej']]

My objective is to compare A and B and delete A intersection B from A, ie, delete A[0][0] in this case.

I tried:

def match():
    for i in A:
        for j in i:
            for k in B:
                for v in k:
                    if j == v:
                        A.remove(j)

list.remove(x) throws a ValueError.

If possible (meaning if the order and the fact that you have "sublists" does not matter), I would first flatten the lists , create sets and then you can easily remove the elements from A that are in B :

>>> from itertools import chain
>>> A = [['ab', 'cd', 'ef', '0', '567'], ['ghy5'], ['pop', 'eye']]
>>> B = [['ab'], ['hi'], ['op'], ['ej']]
>>> A = set(chain(*A))
>>> B = set(chain(*B))
>>> A-B
set(['ghy5', 'eye', 'ef', 'pop', 'cd', '0', '567'])

Or if the order and structure of A matters, you can do (thanks and credits to THC4k ):

>>> remove = set(chain(*B))
>>> A = [[x for x in S if x not in remove] for S in A].

But note: This only works under the assumption that A and B will be always lists of lists.

A naive approach using sets and itertools. You can tweak this further according to your requirements:

#!/usr/bin/env python

a = [['ab', 'cd', 'ef', '0', '567'], ['ghy5'], ['pop', 'eye']]
b = [['ab'], ['hi'], ['op'], ['ej']]

from itertools import chain

# this results in the intersection, here => 'ab'
intersection = set(chain.from_iterable(a)).intersection(
    set(chain.from_iterable(b)))

def nested_loop(iterable):
    """
    Loop over arbitrary nested lists.
    """
    for e in iterable:
        if isinstance(e, list):
            nested_loop(e)
        else:
            if e in intersection:
                iterable.remove(e)
    return iterable

print nested_loop(a)
# => 
# [['cd', 'ef', '0', '567'], ['ghy5'], ['pop', 'eye']]

Edit: To use remove in a situation like this, you can't directly remove j ('ab') in this case from the list a, since it is a nested list. You would have to use A.remove(['ab']) or A.remove([j]) to accomplish this.

Another possibility is the pop(int) method. So A.pop(index) should actually work as well.

Source: http://docs.python.org/tutorial/datastructures.html

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