【问题标题】:Remove item exactly once from list in list comprehension从列表理解中的列表中仅删除一次
【发布时间】:2020-10-23 11:06:24
【问题描述】:

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

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) 删除了listitem 的第一次出现,但由于它返回None,所以输出变为:

[None, None, None]

关于如何使用列表理解(或其他方法)来做到这一点的任何想法?

【问题讨论】:

    标签: python python-3.x list list-comprehension


    【解决方案1】:

    由于您是在原地进行的,因此我更喜欢使用简单的循环而不是列表推导和重建新项目。

    如果你真的想要一个不同的 Python 对象(例如:不在原地),你可以保留这个解决方案和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]]
    

    【讨论】:

    • 感谢deepcopy 的建议,我不得不在我的最终版本中使用它。
    【解决方案2】:

    也许用list.remove 进行简单的for循环就足够了:

    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]]
    

    【讨论】:

      【解决方案3】:

      只是为了好玩,没有removepop的替代方式:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-20
        • 1970-01-01
        • 2012-05-26
        • 2021-10-20
        • 2016-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多