12

我正在尝试创建一个接收 2 个列表并返回仅具有两个列表差异的列表的函数。

例子:

a = [1,2,5,7,9]
b = [1,2,4,8,9]

结果应该打印[4,5,7,8]

到目前为止的功能:

def xor(list1, list2):
    list3=list1+list2
    for i in range(0, len(list3)):
        x=list3[i]
        y=i
        while y>0 and x<list3[y-1]:
            list3[y]=list3[y-1]
            y=y-1
        list3[y]=x

        last=list3[-1]
    for i in range(len(list3) -2, -1, -1):
        if last==list3[i]:
            del list3[i]
        else:
            last=list3[i]

    return list3 
print xor([1,2,5,7,8],[1,2,4,8,9])

第一个 for 循环对其进行排序,第二个循环删除重复项。问题是结果 [1,2,4,5,7,8,9]不是[4,5,7,8],所以它没有完全删除重复项?我可以添加什么来做到这一点。我不能使用任何特殊的模块,.sort、set 或任何东西,基本上只是循环。

4

6 回答 6

18

如果一个元素存在于一个元素中,而另一个元素不存在,则您基本上想将它添加到新列表中。这是一个可以做到的紧凑循环。对于两个列表中的每个元素(用 连接它们list1+list2),如果其中一个不存在,我们添加元素:

[a for a in list1+list2 if (a not in list1) or (a not in list2)]

您可以像现在一样通过元素的显式循环轻松地将其转换为更非 Pythonic 的代码,但老实说,我没有看到任何意义(并不重要):

def xor(list1, list2):
    outputlist = []
    list3 = list1 + list2
    for i in range(0, len(list3)):
        if ((list3[i] not in list1) or (list3[i] not in list2)) and (list3[i] not in outputlist):
             outputlist[len(outputlist):] = [list3[i]]
    return outputlist
于 2013-05-01T04:32:08.397 回答
17

使用set更好

>>> a = [1,2,5,7,9]
>>> b = [1,2,4,8,9]
>>> set(a).symmetric_difference(b)
{4, 5, 7, 8}

感谢@DSM,更好的句子是:

>>> set(a)^set(b)

这两种说法是一样的。但后者更清楚。

更新:对不起,我没有看到最后一个要求:不能使用 set。据我所知,@sashkello 提供的解决方案是最好的。

于 2013-05-01T04:31:38.507 回答
5

注意:这真的很不合情理,只能用作作业答案:)

对两个列表进行排序后,您可以通过执行以下操作找到重复项:

1) 将迭代器放在 A 和 B 的开头

2)如果Aitr大于Bitr,将Bitr的值放入返回列表后推进Bitr

3)否则,如果Bitr大于Aitr,则将Aitr的值放入返回列表后推进Aiter

4) 否则你找到了重复的,提前 Aitr 和 Bitr

于 2013-05-01T04:30:23.230 回答
3

假设您有排序列表,则此代码有效。它在线性时间内起作用,而不是像许多其他给出的解决方案那样是二次的。

def diff(sl0, sl1):
    i0, i1 = 0, 0
    while i0 < len(sl0) and i1 < len(sl1):
        if sl0[i0] == sl1[i1]:
            i0 += 1
            i1 += 1
        elif sl0[i0] < sl1[i1]:
            yield sl0[i0]
            i0 += 1
        else:
            yield sl1[i1]
            i1 += 1
    for i in xrange(i0, len(sl0)):
        yield sl0[i]
    for i in xrange(i1, len(sl1)):
        yield sl1[i]

print list(diff([1,2,5,7,9], [1,2,4,8,9]))
于 2013-05-01T06:33:30.660 回答
3

Try this,

    a = [1,2,5,7,9]
    b = [1,2,4,8,9]
 print set(a).symmetric_difference(set(b))
于 2016-12-29T04:30:49.693 回答
1

简单,但不是特别有效:)

>>> a = [1,2,5,7,9]
>>> b = [1,2,4,8,9]
>>> [i for i in a+b if (a+b).count(i)==1]
[5, 7, 4, 8]

或使用“只是循环”

>>> res = []
>>> for i in a+b:
...  c = 0
...  for j in a+b:
...   if i==j:
...    c += 1
...  if c == 1:
...   res.append(i)
... 
>>> res
[5, 7, 4, 8]
于 2013-05-01T05:04:43.043 回答