在列表理解中仅从列表中删除项目一次

Remove item exactly once from list in list comprehension

我有一个列表列表,具有相应的值:

lists = [[7, 4, 7, 5, 3],
         [1, 3, 2], 
         [4, 5]]
vals = [7, 2, 5]

我想以高效的方式(运行时)从每个列表中恰好删除 vals 中的相应值一次。例如,第一个列表 [7, 4, 7, 5, 3] 应该变成 [4, 7, 5, 3](或 [7, 4, 5, 3],顺序不重要)。

预期输出:

[[4, 7, 5, 3], [1, 3], [4]]

我试过的:

[lst.remove(val) for lst, val in zip(lists, vals)]

list.remove(item) 删除 list 中第一次出现的 item,但由于它 returns None,输出变为:

[None, None, None]

关于如何使用列表推导(或其他方法)执行此操作的任何想法?

既然你这样做了in-place,我更喜欢使用简单的循环而不是列表理解和重建新项目。

如果您真的想要一个不同的 Python 对象(例如:不是 in-place),您可以保留此解决方案和 import copy,以使用 my_new_list = copy.deepcopy(lists)。我认为这是一种更简洁的方法。

lists = [[7, 4, 7, 5, 3],
         [1, 3, 2], 
         [4, 5]]
vals = [7, 2, 5]

for item, to_delete_once in zip(lists, vals):
    index = item.index(to_delete_once)
    if index != -1:
        _ = item.pop(index)

print(lists)
# [[4, 7, 5, 3], [1, 3], [4]]

也许简单的 for-loop 和 list.remove 就足够了:

lists = [[7, 4, 7, 5, 3],
         [1, 3, 2], 
         [4, 5]]
vals = [7, 2, 5]

for l, v in zip(lists, vals):
    try:
        l.remove(v)
    except ValueError:
        pass

print(lists)

打印:

[[4, 7, 5, 3], [1, 3], [4]]

纯属娱乐,不用removepop的替代方法:

new_lists = [ l[::-1][l.index(v):0:-1] + l[l.index(v)+1:] for l, v in zip(lists, vals)]

虽然不确定性能,但为了可读性,我仍然会使用显式循环。