2013-01-11 4 views
4

у меня есть два отсортированных списков положительных целых чисел, которые могут иметь повторяющиеся элементы, и я должен удалить совпадающие пары чисел, по одному из каждого списка:Удаление общих элементов в двух списках

a=[1,2,2,2,3] 
b=[2,3,4,5,5] 

должны стать:

a=[1,2,2] 
b=[4,5,5] 

То есть, 2 и 3 были удалены, потому что они отображаются в обоих списках.

Установки пересечения здесь не могут быть использованы из-за повторяющихся элементов.

Как это сделать?

+1

Я пробовал - но не вижу связи между входом и выходом. Возможно, что еще несколько примеров/дальнейших объяснений помогут ... –

+1

Я думаю, это потому, что 3 должны были быть удалены из обоих списков, а также из одного из 2 – nrussell

+0

. Я понимаю, что перекрывающиеся патчи следует удалять из обеих последовательностей при выполнении выравнивание последовательности. Верный??? –

ответ

3

Чтобы удалить элементы, появляющиеся в обоих списках, используйте следующее:

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

Чтобы создать функцию, которая делает это для вас, просто сделать:

def removeCommonElements(a, b): 
    for e in a[:]: 
     if e in b: 
      a.remove(e) 
      b.remove(e) 

Или возвращать новые списки и не редактировать старые:

def getWithoutCommonElements(a, b): # Name subject to change 
    a2 = a.copy() 
    b2 = b.copy() 
    for e in a: 
     if e not in b: 
      a2.remove(e) 
      b2.remove(e) 
    return a2, b2 

Однако бывший может быть заменен с removeCommonElements следующим образом:

a2, b2 = a.copy(), b.copy() 
removeCommonElements(a2, b2) 

Что бы сохранить a и b, но создать дубликаты без общих элементов.

+0

Это не работает для списков 'a = [1,2,2,2,3]' и 'b = [2,2,3,4,5]', это оставляет 'a = [1,2 , 3] ',' b = [3,4,5] '. – nrussell

+1

Не перебирайте список, удаляя из него элементы. Замените 'iter (a)' на 'a [:]', и он будет работать. – pemistahl

+0

Не совсем то, что мне нужно: [1,1,3], [1,1,1] возвращает [1, 3], [1, 1], должно возвращать [3], [1], поскольку есть два совпадающих 1 –

2

Объект счетчика из коллекций может сделать это довольно лаконично:

from collections import Counter 
a=Counter([1,2,2,2,3]) 
b=Counter([2,3,4,5,5]) 
print list((a-b).elements()) 
print list((b-a).elements()) 

Идея такова:

  1. Прикинь, как часто появляется каждый элемент (например, 2 появляется 3 раза в, и 1 время в b)
  2. Вычитайте количество отсчетов, чтобы определить, сколько лишних раз появляется элемент (например, 2 появляется 3-1 = в 2 раза больше по сравнению с b)
  3. Вывести каждый элемент дополнительного номера раз он появляется (метод коллекции элементов автоматически отбрасывает любые элементы с числом менее 1)

(Внимание: выходные списки не обязательно будут отсортированы)

+0

+1 Прекрасно сделано. Это чистое и быстрое решение. –

2

Учитывая, что списки сортируются, вы могут объединяться/распределяться по элементу, например, например:

x, y = [], [] 

while a and b: 
    if a[0] < b[0]: 
     x.append(a.pop(0)) 
    elif a[0] > b[0]: 
     y.append(b.pop(0)) 
    else: # a[0]==b[0] 
     a.pop(0) 
     b.pop(0) 

x += a 
y += b 
1

Решение, данное компанией @Mahi, является почти правильным. Самый простой способ добиться того, что вы хотите это:

def remove_common_elements(a, b): 
    for i in a[:]: 
     if i in b: 
      a.remove(i) 
      b.remove(i) 
    return a, b 

главное здесь, чтобы сделать копию a написав a[:]. Если вы перебираете список, удаляя из него элементы, вы не получите правильных результатов.

Если вы не хотите изменять списки на месте, сделайте копию обоих списков заранее и верните скопированные списки.

def remove_common_elements(a, b): 
    a_new = a[:] 
    b_new = b[:] 
    for i in a: 
     if i in b_new: 
      a_new.remove(i) 
      b_new.remove(i) 
    return a_new, b_new 
0

Одним из решений было бы создать новую копию a и удалить общие элементы из b.

a = [1,2,2,2,3] 
b = [2,2,3,4,5] 

a_new = [] 
for ai in a: 
    if ai in b: 
     b.remove(ai) 
    else: 
     a_new.append(ai) 

print a_new 
print b 
Смежные вопросы