Как найти разницу между каждым элементом двух списков, когда один из них не является вложенным списком - PullRequest
0 голосов
/ 12 декабря 2018

Я пытаюсь написать алгоритм, который находит разницу между двумя списками, но один из них не является вложенным списком.

Например;

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

Ожидаемый результат:

expected = [[2,3,4],[1,4],[1,2]]

Итак, цель состоит в том, чтобы найти a-b1, где b1 - это каждый элемент в b один за другим.

Я пытался преобразовать их в set(),frozenset() использовал filter() и т. Д., Но ни один из них не был успешным.Либо я получил целочисленную ошибку, либо вывод неправильный (в моем случае).

Моя реальная цель - написать этот алгоритм для топологии, где a - это набор, а b - это топология на * 1021.*.Поэтому я пытаюсь написать закрытый набор этой топологии.

В реальном вопросе a и b - это оба набора, где b - это вложенный set, но я понял, что работать с lists проще, чем sets, чтобы достичь своей цели, но до сих пор ни один из ответов, похожих на мой вопрос (на stackoverflow), не был успешным.

Как найти closed set из given set или найти разницу всех элементов в списке2из списка list1, где list2 является вложенным списком, а list1 - нет.

Ответы [ 4 ]

0 голосов
/ 13 декабря 2018

Я думаю написать собственный метод, который возвращает разницу между двумя списками:

def difference(w, z):
  [w.remove(x) for x in z if x in w]
  return w

Затем использовать метод в цикле for:

res = []
for y in b:
  tmp = a[:]
  if not isinstance(y, list): y = [y]
  res.append(difference(tmp, y))

print(res)
#=> [[2, 3, 4], [1, 4], [1, 2]]


Я надеваюНе знаю, будет ли это полезно, но в этом случае:
a = [1,2,2,3,4]
b = [1,[2,3],[3,4],5]

Результат [[2, 2, 3, 4], [1, 2, 4], [1, 2, 2], [1, 2, 2, 3, 4]]

Вы можете настроить метод, чтобы он лучше подходил вашим потребностям.

0 голосов
/ 12 декабря 2018

Вы можете сделать это с помощью Frozenset или наборов :

a = {1,2,3,4}    # normal set (mutable)
b = [1,frozenset({2,3}),frozenset({3,4})] # frozenset in list to keep ordering 

c = [ (a-x) if isinstance(x,set) else (a-set([x])) for x in b]

print(c)

Вывод:

[set([2, 3, 4]), set([1, 4]), set([1, 2])]

Компонент развернутого списка:

d = []
for top in b:
    d.append( a-top if isinstance(top,set) else a-set([top]) )

# d == c 

a-top это просто сокращение для set.difference .Вот таблица сокращений для наборов (2.7 - все еще действует) .

0 голосов
/ 12 декабря 2018

При работе с математическими наборами вы действительно должны использовать предоставленный тип set в Python.Я написал ваши наборы как наборы Python:

a = {1,2,3,4}
b = [{1},{2,3},{3,4}]

Обратите внимание, что b - это список наборов;Ваша топология на a.Различия между наборами можно найти с помощью оператора - (с двумя наборами A и B, A-B совпадает с математическим A\B):

res = [a-el for el in b]

Вывод:

In [11]: res
Out[11]: [{2, 3, 4}, {1, 4}, {1, 2}]

это список различий между наборами

РЕДАКТИРОВАТЬ Вот способ преобразовать ваши входные данные так, как вы хотели:

Прежде всего, предложите пользователю записать каждый набор в скобках, чтобы иметь регулярный синтаксис, например, например: (1),(1,2),(2,3,4)

Теперь нам нужно регулярное выражение для поиска наборов в результирующей строке "(1),(1,2),(2,3,4)":

import re
inp_list = re.findall(r"(?:\(([\d,]+))", inp_string)

Теперь мы можем начать с решения, упомянутого выше:

res = [{int(number) for number in inp.split(",")} for inp in inp_list]

Чтобы понять регулярное выражение, нажмите здесь

0 голосов
/ 12 декабря 2018

с вашими входами:

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

Теперь я конвертирую a как set

a = set(a)

, затем выполняю установленную разницу между a иэлементы b, просто с помощью теста, чтобы увидеть, является ли элемент простым значением или списком.Преобразуйте обратно каждый элемент в list или используйте sorted для получения возрастающего порядка.

result = [list(a-(set(be if isinstance(be,list) else [be]))) for be in b]

результат:

[[2, 3, 4], [1, 4], [1, 2]]

Небольшой вариант, создающий непосредственно set при передачеnon-list:

result = [list(a-(set(be) if isinstance(be,list) else {be})) for be in b]

И реализация без понимания

a = set(a)
result = []
for be in b:
    if isinstance(be,list):
        result.append(list(a-set(be)))
    else:
        result.append(list(a - {be}))

Работает только с "плоскими" списками, как ваш пример

...