python从嵌套列表中删除元素,如果它存在于另一个列表+中

时间:2016-05-29 19:53:36

标签: python list

我想说我有一个清单:

A = ['x', 'y', 'z']

和另一个 - 嵌套:

B = [['x', 'a', 'b', 'c'], ['y', 'c'], ['x', 'a', 'c', 'z']]

如何删除' z'根据' z'在A中,子列表B的每个第一个元素[0]都在列表A?

所以基本上我需要从这样一个嵌套列表中检测所有元素,其中元素在A中并且它不在那个嵌套列表的第一个位置?

我正在尝试这个但是堆积起来:

for i in B:
    for j in i[1:]:
        if j in A:
            del j

但我遗失了一些东西。

2 个答案:

答案 0 :(得分:1)

使用列表推导来就地更新列表:

for sublist in B:
    if sublist[0] in A:
        sublist[1:] = [v for v in sublist[1:] if v not in A]
循环中的

j只是对子列表中值的另一个引用。 del j删除了一个引用,但列表仍包含该引用。您可以使用del listobj[index]listobj.pop(value)从列表中删除值(注意那些含义的微妙之处),但是如果您不小心,则在迭代时从列表中删除将导致项目被跳过。

通过分配切片,您可以就地替换列表中的这些元素。

请注意,您可能希望将A设为设置;使用集合时,成员资格测试要快得多:

Aset = set(A)

for sublist in B:
    if sublist[0] in Aset:
        sublist[1:] = [v for v in sublist[1:] if v not in Aset]

演示:

>>> A = ['x', 'y', 'z']
>>> B = [['x', 'a', 'b', 'c'], ['y', 'c'], ['x', 'a', 'c', 'z']]
>>> Aset = set(A)
>>> for sublist in B:
...     if sublist[0] in Aset:
...         sublist[1:] = [v for v in sublist[1:] if v not in Aset]
...
>>> B
[['x', 'a', 'b', 'c'], ['y', 'c'], ['x', 'a', 'c']]

答案 1 :(得分:1)

您可以使用嵌套列表解析:

>>> [sub[:1]+[i for i in sub[1:] if not(sub[0] in A and i in A)] for sub in B]
[['x', 'a', 'b', 'c'], ['y', 'c'], ['x', 'a', 'c']]

此处,您将保留不符合删除条件的子列表(从第二项到另一项)中的项目。