Python - list.remove(x) 的替代方法?
我想比较两个列表。一般来说,这没什么问题,因为我通常会用一个嵌套的循环,把它们的交集添加到一个新的列表里。不过在这个情况下,我需要把列表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) 也应该可以正常工作。
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].
但请注意:这只在假设A
和B
始终是列表中的列表的情况下有效。