2010-06-02 2 views
1

Я хочу сравнить два списка. Как правило, это не проблема, поскольку я обычно использую цикл вложенных циклов и добавляю пересечение в новый список. В этом случае нужно удалить пересечение А и В из А.Python - альтернатива list.remove (x)?

A = [['ab', 'cd', 'ef', '0', '567'], ['ghy5'], ['pop', 'eye']] 

B = [['ab'], ['hi'], ['op'], ['ej']] 

Моя цель состоит в том, чтобы сравнить А и В и удалить пересечение B из A, т.е. удалить A [0] [0] в этом случае.

Я пробовал:

def match(): 
    for i in A: 
     for j in i: 
      for k in B: 
       for v in k: 
        if j == v: 
         A.remove(j) 

list.remove (х) бросает ValueError.

ответ

9

Если возможно (то есть, если порядок и тот факт, что у вас есть «подсписки» не имеет значения), я бы первый flatten the lists, создать sets, а затем вы можете легко удалить элементы из A, которые находятся в B:

>>> from itertools import chain 
>>> A = [['ab', 'cd', 'ef', '0', '567'], ['ghy5'], ['pop', 'eye']] 
>>> B = [['ab'], ['hi'], ['op'], ['ej']] 
>>> A = set(chain(*A)) 
>>> B = set(chain(*B)) 
>>> A-B 
set(['ghy5', 'eye', 'ef', 'pop', 'cd', '0', '567']) 

Или, если порядок и структура A вопросов, вы можете сделать (спасибо и кредиты THC4k):

>>> remove = set(chain(*B)) 
>>> A = [[x for x in S if x not in remove] for S in A]. 

Но обратите внимание: Это работает только в предположении, что A и B будут всегда списки списков.

+0

@ THC4k: Если вы хотите представить свой комментарий в качестве ответа, я отвечу на исходный ответ. –

+2

Нет, ваше замечательное, я просто «надеюсь», что есть веская причина для этого списка списков ;-) –

1

Редактировать: Чтобы использовать удаление в подобной ситуации, вы не можете удалить j ('ab') в этом случае из списка a, так как это вложенный список. Для этого вам нужно будет использовать A.remove (['ab']) или A.remove ([j]).

Другая возможность - метод pop (int). Поэтому A.pop (index) также должен работать.

Источник: http://docs.python.org/tutorial/datastructures.html

+0

? 'j' всегда является элементом списков в' A'. Это не показатель. –

+0

К сожалению, отредактирован ответ, чтобы отразить это. – Tyler

4

Наивный подход с использованием наборов и itertools. Вы можете изменить это в соответствии с вашими требованиями:

#!/usr/bin/env python 

a = [['ab', 'cd', 'ef', '0', '567'], ['ghy5'], ['pop', 'eye']] 
b = [['ab'], ['hi'], ['op'], ['ej']] 

from itertools import chain 

# this results in the intersection, here => 'ab' 
intersection = set(chain.from_iterable(a)).intersection(
    set(chain.from_iterable(b))) 

def nested_loop(iterable): 
    """ 
    Loop over arbitrary nested lists. 
    """ 
    for e in iterable: 
     if isinstance(e, list): 
      nested_loop(e) 
     else: 
      if e in intersection: 
       iterable.remove(e) 
    return iterable 

print nested_loop(a) 
# => 
# [['cd', 'ef', '0', '567'], ['ghy5'], ['pop', 'eye']] 
Смежные вопросы