2013-05-01 129 views
8

我試圖創建一個函數,它需要2個列表並返回只有兩個列表有差異的列表。比較兩個列表並僅打印差異? (XORing兩個列表)

實施例:

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或任何東西,只是基本上循環。

回答

12

基本上你想添加一個元素到你的新列表,如果它存在於一個而不存在於另一個。這是一個緊湊的循環,可以做到這一點。對於在兩個列表(與list1+list2將它們連接起來),我們添加元素,如果它不存在於其中的每個元素:

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

你可以將它通過元素作爲明確的循環很容易轉變成一個更unPythonic碼你現在有,但老實說,我沒有看到一個點(這不是問題):

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 
+1

嗯,列表解析 – Patashu 2013-05-01 04:33:30

+0

我想我明白它在做什麼,但是我會怎樣使這成爲一個完整的循環,並將該循環添加到原來的功能,或者是否會自行工作... – user2314520 2013-05-01 04:55:56

+0

這是一個單線程,它會執行您正在創建的功能...您通過list1 + list2循環元素x並且有兩個if:1.如果list1中的元素使得flag1 = True,2.如果list2中的元素使得flag2 = True;如果(flag1和flag2)!= True且x不在outputlist中,則將其添加到outputlist。 – sashkello 2013-05-01 05:00:42

5

注:這是真的unpythonic,你已經整理兩份名單後,只應作爲一門功課的答案:)

,您可以通過執行以下操作找到重複:在

1)將迭代器A的開始和B

2)如果Aitr大於BITR更大,放置BITR的值在返回列表

3)否則,如果BITR大於Aitr更大之後前進BITR,放置Aitr的值在後推進Aiter返回列表

4)否則,你找到了一個副本,推進Aitr和BITR

+0

爲什麼你認爲你的做法是unpythonic? – 2013-05-01 05:02:31

+0

@gnibbler看到盛的答案,我認爲pythonic – Patashu 2013-05-01 05:03:04

+0

這依賴於所有可哈希元素。 (他們可能是) – 2013-05-01 05:06:35

10

使用一套更好

>>> 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提供的解決方案是最好的。

+1

非家庭作業的好答案,但'我不能使用任何特殊模塊,.sort,set或任何東西,只是基本循環。' – Patashu 2013-05-01 04:31:47

+2

爲什麼不簡單地設置(a)^ set(b)',如果我們使用集合? – DSM 2013-05-01 04:33:14

+0

@DSM謝謝,你的建議比較好。我只是忘記了語法。 – Sheng 2013-05-01 04:33:53

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

呵呵,不錯! – sashkello 2013-05-01 05:05:20

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])) 
+0

+1爲線性解決方案。一般來說,[你可以調整它來接受任何迭代](http:// ideone。com/8bKqVB),本質上實現了[@ Patashu算法](http://stackoverflow.com/a/16312759/4279)。 – jfs 2013-05-02 01:39:57

2

試試這個,

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