Python 从列表中删除公共元素

Python 从列表中删除公共元素,python,list,python-2.7,Python,List,Python 2.7,在这些清单中: a=[2,6,79,10] b=[6,7,2,0,8,5] 所需的输出将是: a=[79,10] b=[7,0,8,5] 为什么这个代码不起作用 def cel(a,b): for x in a: if x in b: b.remove(x) a.remove(x) 为此,可以使用集合操作: i = set(a).intersection(set(b)) a = list(set(a).differen

在这些清单中:

a=[2,6,79,10]
b=[6,7,2,0,8,5]
所需的输出将是:

a=[79,10]
b=[7,0,8,5]
为什么这个代码不起作用

def cel(a,b):
    for x in a:
        if x in b:
            b.remove(x)
            a.remove(x)

为此,可以使用集合操作:

i = set(a).intersection(set(b))
a = list(set(a).difference(i))
b = list(set(b).difference(i))
编辑我试图调试您的原始代码,并意识到每当删除一个数字时,它都会跳过一个数字。在谷歌搜索之后,我发现由于一些内部索引问题,在迭代时修改列表并不是一种既定行为。最简单的解决方法是在for循环中使用原始数组的副本,如下所示:

for x in a[:]:
    if x in b:
        b.remove(x)
        a.remove(x)

为此,可以使用集合操作:

i = set(a).intersection(set(b))
a = list(set(a).difference(i))
b = list(set(b).difference(i))
编辑我试图调试您的原始代码,并意识到每当删除一个数字时,它都会跳过一个数字。在谷歌搜索之后,我发现由于一些内部索引问题,在迭代时修改列表并不是一种既定行为。最简单的解决方法是在for循环中使用原始数组的副本,如下所示:

for x in a[:]:
    if x in b:
        b.remove(x)
        a.remove(x)

@gokcehan答案中的保序算法是立方的
O(n**3)
。即使对于中等大小的列表也是非常低效的(编程Pearls书中有一个例子,其中Basic中的线性算法优于C中的立方算法(分钟vs.天))

您可以保留顺序并在线性时间内运行:

common = set(a).intersection(b)
a = [x for x in a if x not in common]
b = [x for x in b if x not in common]
您可以在以下位置执行此操作:

def remove_items(lst, items):
    items = set(items) # unnecessary in your case
    pos = 0
    for x in lst:
        if x not in items:
           lst[pos] = x # save
           pos += 1
    del lst[pos:]

common = set(a).intersection(b)
remove_items(a, common)
remove_items(b, common)

在@gokcehan的答案中,保持顺序的算法是立方的
O(n**3)
。即使对于中等大小的列表也是非常低效的(编程Pearls书中有一个例子,其中Basic中的线性算法优于C中的立方算法(分钟vs.天))

您可以保留顺序并在线性时间内运行:

common = set(a).intersection(b)
a = [x for x in a if x not in common]
b = [x for x in b if x not in common]
您可以在以下位置执行此操作:

def remove_items(lst, items):
    items = set(items) # unnecessary in your case
    pos = 0
    for x in lst:
        if x not in items:
           lst[pos] = x # save
           pos += 1
    del lst[pos:]

common = set(a).intersection(b)
remove_items(a, common)
remove_items(b, common)

您的代码应该做什么?顶部的示例是所需的输出,还是运行时得到的结果?在对列表进行迭代时,不能修改该列表。@dpassage我需要从列表中删除公共元素代码应该做什么?顶部的示例是所需的输出,还是运行时得到的结果?在对列表进行迭代时,不能修改该列表。@dpassage我需要从列表中删除公共元素这将丢失原始顺序(这可能很重要,也可能不重要)。如果我需要正确的顺序,则最后一个示例具有
O(n**3)
运行时间。对于a[:]中的x:如果b.count(x)>0:b.remove(x)a.remove(x)这将丢失原始顺序,但是(这可能重要,也可能不重要)。如果我需要正确的顺序,那么?最后一个示例有
O(n**3)
运行时间。对于a[:]中的x:如果b.count(x)>0:b.remove(x)a.remove(x)我喜欢你的解决方案,但我认为它们的可读性很差。请记住,
O(n^3)
仍然是一个多项式算法,因此它在大多数情况下都是可以接受的。我们需要小心避免过早的优化。@gokchehan:基于列表理解的解决方案既简单又高效。认为
O(n**3)
解决方案更可取是不合理的,因为必须对其进行调试才能使其正确。第二个例子要复杂得多,幸运的是它几乎不需要。它是用来显示如何在原地完成的。
O(n^3)
解决方案是用来显示与所讨论的原始算法最接近的修复,正如前面所述,而不是作为一种更好的方式。同样,这个问题不是关于最有效的方法,因此你的第二个解决方案对我来说或多或少是垃圾。然而,我同意你的第一个解决方案与我建议的第一个解决方案是相当有用的,如果顺序问题最终不是这个问题的情况,你的解决方案可能是最好的解决方案。我喜欢你的解决方案,但我认为它们的可读性较差。请记住,
O(n^3)
仍然是一个多项式算法,因此它在大多数情况下都是可以接受的。我们需要小心避免过早的优化。@gokchehan:基于列表理解的解决方案既简单又高效。认为
O(n**3)
解决方案更可取是不合理的,因为必须对其进行调试才能使其正确。第二个例子要复杂得多,幸运的是它几乎不需要。它是用来显示如何在原地完成的。
O(n^3)
解决方案是用来显示与所讨论的原始算法最接近的修复,正如前面所述,而不是作为一种更好的方式。同样,这个问题不是关于最有效的方法,因此你的第二个解决方案对我来说或多或少是垃圾。然而,我同意,你的第一个解决方案与我建议的第一个解决方案是非常有用的,如果订单问题最终证明不是这个问题,你的解决方案可能是最好的解决方案。