как вычесть один список из другого, включая дубликаты

#python #python-3.x

#питон #python-3.x

Вопрос:

У меня есть 2 списка

Включен большой список с некоторыми элементами, имеющими дубликаты super_set_list = [1,1,2,3,3,4,4,4,5,6,7,8,9]

Другой — это подмножество большого списка, также с дубликатами sub_set_list = [1,2,3,3,4,4,6,7,9]

Я хочу разницу, вот так diff = [1,4,5,8]

Не знаю, как бы я поступил по этому поводу

Комментарии:

1. Вы можете использовать счетчик из коллекций

2. @Learningisamess да, конечно, и тогда вы сможете различать два счетчика. Так что один вариант… functools.reduce(list.__add__, [[val]*n for val, n in (Counter(super_set_list) - Counter(sub_set_list)).items()])

3. Если порядок не имеет значения, используйте наборы и найдите разницу.

4. Альтернативный способ написать вышесказанное: [val for val, n in (Counter(super_set_list) - Counter(sub_set_list)).items() for _ in range(n)]

5. Предположим, что вы sub_set_list вообще не содержали никаких 1 элементов: сколько раз вы хотели бы, чтобы это число 1 появлялось diff : только один или два раза?

Ответ №1:

Вы можете использовать Counter

 super_set_list = [1,1,1,2,3,3,4,4,4,5,6,7,8,9] sub_set_list = [1,2,3,3,4,4,6,7,9]  from collections import Counter super_counter = Counter(super_set_list)   

super_counter = Счетчик({1: 3, 4: 3, 3: 2, 2: 1, 5: 1, 6: 1, 7: 1, 8: 1, 9: 1})

Для каждого элемента в sub_set_list уменьшите количество в в super_counter

 for item in sub_set_list:  super_counter[item]-=1  

Теперь super_counter = Счетчик({1: 2, 4: 1, 5: 1, 8: 1, 2: 0, 3: 0, 6: 0, 7: 0, 9: 0})

Наконец, просто выберите элементы, у которых осталось некоторое количество (но добавьте их столько раз).

 diff=[] for k,v in super_counter.items():  for _ in range(v):  diff.append(k) print(diff) # [1, 1, 4, 5, 8]  

Комментарии:

1. Вам не нужно проверять item in super_counter , потому что несуществующие элементы имеют количество 0 . Вам не нужно проверять super_counter[item] gt;= 1 , потому что вы все равно проверяете v gt; 0 позже при составлении списка

2. Пример в вопросе является плохим, потому что разница в количестве элементов между двумя списками всегда равна либо 0, либо 1, но описание как «разница» подсказывает мне, что в принципе элементы могут потребоваться несколько раз, diff если разница между числами больше 1, чего ваш код не сделал бы.

3. @alani внесла правку, чтобы учесть это.

Ответ №2:

Вы можете пройтись по списку поднаборов и удалить элемент в списке супернаборов один за другим следующим образом:

 super_set_list = [1,1,2,3,3,4,4,4,5,6,7,8,9] sub_set_list = [1,2,3,3,4,4,6,7,9]  for item in sub_set_list:  if item in super_set_list:  super_set_list.remove(item) print(super_set_list)