Python - list.remove(x) 的替代方法?

1 投票
3 回答
4542 浏览
提问于 2025-04-15 23:27

我想比较两个列表。一般来说,这没什么问题,因为我通常会用一个嵌套的循环,把它们的交集添加到一个新的列表里。不过在这个情况下,我需要把列表A和B的交集从A中删除。

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

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

我的目标是比较A和B,并把A和B的交集从A中删除,也就是说,要删除A[0][0]这个元素。

我尝试过:

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)时出现了一个ValueError错误。

3 个回答

1

编辑:在这种情况下,如果你想从列表 a 中删除 j('ab'),是不能直接删除的,因为它是一个嵌套列表。你需要使用 A.remove(['ab']) 或者 A.remove([j]) 来实现这个操作。

另外一种方法是使用 pop(int) 方法。所以 A.pop(index) 也应该可以正常工作。

来源: http://docs.python.org/tutorial/datastructures.html

4

这里介绍了一种简单的方法,使用集合和itertools库。你可以根据自己的需求进一步调整这个方法:

#!/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']]
9

如果可以的话(也就是说,如果顺序和你有“子列表”这件事不重要),我建议先把列表“扁平化”,然后创建一些集合,这样你就可以轻松地从A中去掉那些在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'])

或者如果A的顺序和结构很重要,你可以这样做(感谢THC4k的贡献):

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

但请注意:这只在假设AB始终是列表中的列表的情况下有效。

撰写回答