【问题标题】:Python - Remove a set of a list from another listPython - 从另一个列表中删除一组列表
【发布时间】:2013-09-20 02:33:18
【问题描述】:
array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
array2 = [1, 2, 2, 2, 5, 6, 6, 6, 9]

temp = set(array2)

array1.remove(temp)

Traceback (most recent call last):
  File "Sudoku V2.py", line 6, in <module>
    array1.remove(temp)
ValueError: list.remove(x): x not in list

【问题讨论】:

  • 错误信息的哪一部分令人困惑? set(array2) 不在 array1 中。
  • 您实际上想从 array1 中删除什么? array2 的每个元素?
  • 你的问题是什么???
  • 一般来说,如果您显示所需的输出而不是让我们猜测它会有所帮助。请参阅SSCCE 获取指导。

标签: python list set


【解决方案1】:

这是可以帮助您解决问题的三个解决方案:

array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
array2 = [1, 2, 2, 2, 5, 6, 6, 6, 9]


array = [i for i in array1 if i not in array2]
print(array)


o = list(set(array1) - set(array2))
print(o)

from collections import OrderedDict

p = OrderedDict() 
p['array'] = list(set(array1) - set(array2))
print(*p.values())

【讨论】:

    【解决方案2】:

    如果您不关心结果中元素的顺序,或者不关心重复的元素,set.difference,就像 Óscar López 的回答一样,正是您想要的。

    如果您确实关心顺序和保留重复项,最简单的方法是构建一个新列表,过滤掉 array2 中的列表:

    set2 = set(array2)
    array1 = [item for item in array1 if item not in set2]
    

    如果您需要就地破坏性地修改 array1 而不是构建一个新的,那么一次破坏性地替换 array1 的内容几乎总是更简单:

    array1[:] = [item for item in array1 if item not in set2]
    

    如果你真的想逐个元素地修改它,最好的方法是向后迭代array1,就地删除:

    set2 = set(array2)
    for i, value in enumerate(array1)[::-1]:
        if value in set2:
            del array1[i]
    

    最后,您可以按照 flornquake 建议的方式进行操作,但这需要二次时间而不是线性时间,因为它没有利用 set;对于set2 中的每个元素,它执行线性array1.remove

    【讨论】:

    • 你应该只将array2转换为一个集合
    • 我的意思是array1 = [item for item in array1 if item not in set(array2)] 应该是s = set(array2); array1 = [item for item in array1 if item not in s] 以避免二次行为。
    • @flornquake:谢谢。在后面的示例中我已经这样做了,但不是第一个。固定。
    【解决方案3】:

    remove() 方法接受列表的单个元素,因此我们必须为每个元素调用一次:

    for item in set(array2):
        array1.remove(item)
    

    其他方法,例如 Óscar's 和 abanert's 更好,但它们更惯用且效率更高。

    【讨论】:

    • 您根本没有真正使用这里的集合;你只是在遍历所有元素……
    • 你是对的,感谢您指出这一点。我已经编辑了我的答案以澄清这一点,但我将留下其余部分,因为它解释了 OP 滥用的删除方法。
    【解决方案4】:

    试试这个:

    array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    array2 = [1, 2, 2, 2, 5, 6, 6, 6, 9]
    set(array1).difference(array2)
    => set([3, 4, 7, 8])
    

    上面使用了集合的difference() 方法,它返回一个新集合,其中的元素不在作为参数接收的可迭代对象中。请注意,无需将 array2 转换为 set 即可。

    还要注意,通过使用集合,所有重复的元素都将被删除,并且不一定会保留可迭代对象的原始顺序。如果这是一个问题,请尝试以下替代解决方案:

    [x for x in array1 if x not in array2]
    => [3, 4, 7, 8]
    

    【讨论】:

    • downvoters:想发表评论吗?太好了,有些人不考虑答案是否正确就匆忙投反对票,然后不露面删除投反对票,或者至少解释原因。
    • 太完美了!非常感谢!
    • 我没有投反对票,但我怀疑谁投了反对票,因为你的答案返回了一个集合,破坏了原始array1 中的任何顺序,以及任何重复的值。我认为 OP 的问题没有充分的理由假设这是不可接受的。但是,如果您解释了这样做的后果(如果不可接受,则提供不同的替代方案),这将是一个更好的答案。
    • @YuraB 太棒了!如果此答案对您有帮助,请单击其左侧的复选标记来考虑accepting ;)
    • 你的答案正是我想要的,奥斯卡。非常感谢您的帮助!
    【解决方案5】:

    s -> 序列

    s.remove(x) remove the first item from s where s[i] == x
    
    remove raises ValueError when x is not found in s.
    

    http://docs.python.org/3/library/stdtypes.html#index-23

    array1 中的所有元素都不是集合。 array1 中的所有元素都是整数。

    【讨论】:

      【解决方案6】:

      你想要array1 - array2吗?

      set1 = set(array1)

      set2 = set(array2)

      set1.difference(set2) 就是你想要的。

      【讨论】:

      • 无需将array2 转换为集合,difference 将可迭代作为参数,请参阅我的答案。
      • 欢迎来到Stack Overflow!您可以使用四个空格缩进代码以很好地格式化它,或者用`字符(反引号)将其包围
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-13
      • 1970-01-01
      • 2016-11-06
      • 1970-01-01
      • 2016-08-28
      • 1970-01-01
      相关资源
      最近更新 更多