Как вычесть из одного массива другой?
вот код
Как сделать так, чтобы после нахождения максимума и минимума оставить список без этих двух элементов?
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Как из одного массива пользовательских объектов вычесть другой
Собственно сабж. нужно это мне тут using assembly .\lib\LiteDB.dll using namespace.
Как вычесть из одного класса другой?
Вопрос такой, есть 2 класса в одном минуты секунды, во втором только секунды, не могу понять как.
Вычесть из одного массива байт другой массив байт
Здравствуйте! Подскажите что нужно сделать чтобы из одного массива байт вычесть другой массив байт!
Из одного списка, поэлементно вычесть другой
Списки могут быть разной длины. Помогите, сам не могу
Присвоить значения переменных, которые были получены из одного TextBox в другой и вычесть из него 1
Нужно присвоить значения переменных, которые были получены из тексбокс, в другой текст бокс и .
2421 / 1463 / 633
Регистрация: 01.11.2021
Сообщений: 2,269
Только будет ошибка, если список меньше 2 элементов.
1 2 3 4 5
a= list(map(int, input().split())) print(a) a.remove(max(a)) a.remove(min(a)) print(a)
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь
Как из одного двумерного массива сформировать другой
отпечатать массив Х в виде матрицы.составить другой массив Y из элементов массива Х, заменив нулями.
Как записать столбец из одного массива в другой?
Помогите решить задачу: Записать второй столбец массива А в массив В. Не знаю как записать столбец.
Как скопировать содержимое одного массива в другой?
Всё тот же магазин. Осталось только одно, копировать содержимое из одного массива, в другой. Я уже.
Как переключить указатель с одного массива на другой
Значит смысл следующий. Есть массив int Massiv; далее будет создан второй массив int Massiv; Я хочу.
Как переместить элементы одного массива в другой?
переписать элементы удовлетворяющих условию -1<=x<=1 из массива X в массив Y Я написал программу.
Пересечение списков, совпадающие элементы двух списков
В данной задаче речь идет о поиске элементов, которые присутствуют в обоих списках. При этом пересечение списков и поиск совпадающих (перекрывающихся) элементов двух списков будем считать несколько разными задачами.
Если даны два списка, в каждом из которых каждый элемент уникален, то задача решается просто, так как в результирующем списке не может быть повторяющихся значений. Например, даны списки:
[5, 4, 2, ‘r’, ‘ee’] и [4, ‘ww’, ‘ee’, 3]
Областью их пересечения будет список [4, ‘ee’] .
Если же исходные списки выглядят так:
[5, 4, 2, ‘r’, 4, ‘ee’, 4] и [4, ‘we’, ‘ee’, 3, 4] ,
то списком их совпадающих элементов будет [4, ‘ee’, 4] , в котором есть повторения значений, потому что в каждом из исходных списков определенное значение встречается не единожды.
Начнем с простого — поиска области пересечения. Cначала решим задачу «классическим» алгоритмом, не используя продвинутые возможностями языка Python: будем брать каждый элементы первого списка и последовательно сравнивать его со всеми значениями второго.
a = [5, [1, 2], 2, 'r', 4, 'ee'] b = [4, 'we', 'ee', 3, [1, 2]] c = [] for i in a: for j in b: if i == j: c.append(i) break print(c)
Результат выполнения программы:
[[1, 2], 4, 'ee']
Берется каждый элемент первого списка (внешний цикл for ) и последовательно сравнивается с каждым элементом второго списка (вложенный цикл for ). В случае совпадения значений элемент добавляется в третий список c . Команда break служит для выхода из внутреннего цикла, так как в случае совпадения дальнейший поиск при данном значении i бессмыслен.
Алгоритм можно упростить, заменив вложенный цикл на проверку вхождения элемента из списка a в список b с помощью оператора in :
a = [5, [1, 2], 2, 'r', 4, 'ee'] b = [4, 'we', 'ee', 3, [1, 2]] c = [] for i in a: if i in b: c.append(i) print(c)
Здесь выражение i in b при if по смыслу не такое как выражение i in a при for . В случае цикла оно означет извлечение очередного элемента из списка a для работы с ним в новой итерации цикла. Тогда как в случае if мы имеем дело с логическим выражением, в котором утверждается, что элемент i есть в списке b . Если это так, и логическое выражение возвращает истину, то выполняется вложенная в if инструкция, то есть элемент i добавляется в список c .
Принципиально другой способ решения задачи – это использование множеств. Подходит только для списков, которые не содержат вложенных списков и других изменяемых объектов, так как встроенная в Python функция set() в таких случаях выдает ошибку.
a = [5, 2, 'r', 4, 'ee'] b = [4, 1, 'we', 'ee', 'r'] c = list(set(a) & set(b)) print(c)
['ee', 4, 'r']
Выражение list(set(a) & set(b)) выполняется следующим образом.
- Сначала из списка a получают множество с помощью команды set(a) .
- Аналогично получают множество из b .
- С помощью операции пересечения множеств, которая обозначается знаком амперсанда & , получают третье множество, которое представляет собой область пересечения двух исходных множеств.
- Полученное таким образом третье множество преобразуют обратно в список с помощью встроенной в Python функции list() .
Множества не могут содержать одинаковых элементов. Поэтому, если в исходных списках были повторяющиеся значения, то уже на этапе преобразования этих списков во множества повторения удаляются, а результат пересечения множеств не будет отличаться от того, как если бы в исходных списках повторений не было.

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

В список пересечения попадают оба равных друг другу значения из первого списка. Это происходит потому, что когда цикл извлекает, в данном случае, вторую 4-ку из первого списка, выражение i in b также возвращает истину, как и при проверке первой 4-ки. Следовательно, выражение c.append(i) выполняется и для второй четверки.
Чтобы решить эту проблему, добавим дополнительное условие в заголовок инструкии if . Очередной значение i из списка a должно не только присутствовать в b , но его еще не должно быть в c . То есть это должно быть первое добавление такого значения в c :
a = [5, 2, 'r', 4, 'ee', 4] b = [4, 'we', 'ee', 3] c = [] for i in a: if i in b and i not in c: c.append(i) print(c)
[4, 'ee']
Теперь усложним задачу. Пусть если в обоих списках есть по несколько одинаковых значений, они должны попадать в список совпадающих элементов в том количестве, в котором встречаются в списке, где их меньше. Или если в исходных списках их равное количетво, то такое же количество должно быть в третьем. Например, если в первом списке у нас три 4-ки, а во втором две, то в третьем списке должно быть две 4-ки. Если в обоих исходных по две 4-ки, то в третьем также будет две.
Алгоритмом решения такой задачи может быть следующий:
- В цикле будем перебирать элементы первого списка.
- Если на текущей итерации цикла взятого из первого списка значения нет в третьем списке, то только в этом случае следует выполнять все нижеследующие действия. В ином случае такое значение уже обрабатывалось ранее, и его повторная обработка приведет к добавлению лишних элементов в результирующий список.
- С помощью спискового метода count() посчитаем количество таких значений в первом и втором списке. Выберем минимальное из них.
- Добавим в третий список количество элементов с текущим значением, равное ранее определенному минимуму.
a = [5, 2, 4, 'r', 4, 'ee', 1, 1, 4] b = [4, 1, 'we', 'ee', 'r', 4, 1, 1] c = [] for item in a: if item not in c: a_item = a.count(item) b_item = b.count(item) min_count = min(a_item, b_item) # c += [item] * min_count for i in range(min_count): c.append(item) print(c)
[4, 4, 'r', 'ee', 1, 1]
Если значение встречается в одном списке, но не в другом, то метод count() другого вернет 0. Соответственно, функция min() вернет 0, а цикл с условием i in range(0) не выполнится ни разу. Поэтому, если значение встречается в одном списке, но его нет в другом, оно не добавляется в третий.
При добавлении значений в третий список вместо цикла for можно использовать объединение списков с помощью операции + и операцию повторения элементов с помощью * . В коде выше данный способ показан в комментарии.
X Скрыть Наверх
Решение задач на Python
Python-сообщество
![]()
- Начало
- » Python для новичков
- » Вычитание списков?
#1 Окт. 24, 2012 11:21:01
tfox Зарегистрирован: 2012-04-13 Сообщения: 55 Репутация: 0 Профиль Отправить e-mail
Вычитание списков?
Как из одного списка удалить все элементы которые есть в другом списке?
l1 = [1, 2, 3] l2 = [2] # сложение списков работает l3 = l1 + l2 print l3 # а это не работает :( l3 = l1 - l2 print l3
#2 Окт. 24, 2012 11:29:09
GaiveR От: Зарегистрирован: 2011-08-13 Сообщения: 122 Репутация: 16 Профиль Отправить e-mail
Вычитание списков?
#3 Окт. 24, 2012 12:17:52
dimy44 От: Евпатория Зарегистрирован: 2012-04-21 Сообщения: 463 Репутация: 42 Профиль
Вычитание списков?
>>> lst1 = range(10) >>> lst2 = [1, 1, 4, 5] >>> col = set(lst2) >>> lst1 = [i for i in lst1 if i not in col] >>> lst1 [0, 2, 3, 6, 7, 8, 9] >>>
это на тот случай, если важно сохранить последовательность элементов уменьшаемого списка.
#4 Окт. 24, 2012 14:14:04
tfox Зарегистрирован: 2012-04-13 Сообщения: 55 Репутация: 0 Профиль Отправить e-mail
Вычитание списков?
dimy44
это на тот случай, если важно сохранить последовательность элементов уменьшаемого списка.
Да. Мне важно сохранить последовательность элементов уменьшаемого списка.
Это выражение тоже сохраняет элементы в том же порядке как они и были:
GaiveR
l3 = list(set(l1).difference(l2))
#5 Окт. 24, 2012 15:01:03
dimy44 От: Евпатория Зарегистрирован: 2012-04-21 Сообщения: 463 Репутация: 42 Профиль
Вычитание списков?
Это уж как карта ляжет.
>>> lst1 = [1, 5, 1, 3, 4, 2, 6]
>>> lst2 = [1, 2]
>>> list(set(lst1).difference(lst2))
[3, 4, 5, 6]
>>>
#6 Окт. 24, 2012 16:33:38
dimy44 От: Евпатория Зарегистрирован: 2012-04-21 Сообщения: 463 Репутация: 42 Профиль
Вычитание списков?
И да, забыл еще указать, что если у Вас в списке будут повторяющиеся элементы, которые не нужно вычитать, то даже если предположить, что очередность не важна, все-равно set испортит Ваш список, т.к. уберет дублирующие элементы.
Быстрое вычитание списков
В случае, когда количество элементов списков A и B высоко (порядка 100 000 и выше), способ естественно работает очень медленно. Возможно ли реализовать подобный поиск быстрее? Если да, то как именно?
Отслеживать
Denis Leonov
задан 22 мар 2017 в 6:45
Denis Leonov Denis Leonov
540 4 4 золотых знака 10 10 серебряных знаков 24 24 бронзовых знака
4 ответа 4
Сортировка: Сброс на вариант по умолчанию
i in B это O(m) операция для списков ( m = len(B) ). Поэтому ваш код это O(n * m) алгоритм ( n = len(A) ), то есть для длин списков ~ 100_000 (10 5 ) ваша реализация вычитания списков займёт порядка 10_000_000_000 (10 10 ) операций. Если при работе с чуть бОльшими списками в телефоне вдруг всё начинает тормозить, когда для маленьких списков всё летает, то одно из вероятных объяснений, что программист использовал квадратичный алгоритм вместо линейного (или квази-линейного).
Можно значительно улучшить производительность (если все элементы списка хэшируются) с помощью set() :
Bset = frozenset(B) C = [item for item in A if item not in Bset] # C = A - B
item in Bset это O(1) операция (в среднем). Поэтому C список вычисляется за O(n + m) (линейный алгоритм), что значительно лучше O(n * m) для больших B .
Обратите внимание, что set(A) не вызывается, иначе получатся результаты отличные от кода в вашем вопросе, если в A есть повторяющиеся элементы или если вы хотите исходный порядок в A сохранить:
>>> A = "abracadabra" >>> B = ['a', 'b', 'c'] >>> Bset = frozenset(B) >>> [item for item in A if item not in Bset] ['r', 'd', 'r']
Обратите внимание, ‘r’ встречается дважды в результате и относительный порядок ‘r’ и ‘d’ сохранён.
Если элементы не являются хэшируемыми (к примеру вложенные списки), то можно отсортировать B и использовать двоичный поиск, чтобы определить присутствует ли элемент в отсортированной последовательности:
from bisect import bisect_left def contains(sorted_seq, item): i = bisect_left(sorted_seq, item) return i != len(sorted_seq) and sorted_seq[i] == item
>>> A = map(list, "abracadabra") >>> B = [['a'], ['b'], ['c']] >>> Bsorted = sorted(B) >>> [item for item in A if not contains(Bsorted, item)] [['r'], ['d'], ['r']]
Это O((n + m) * log m) алгоритм. log() функция достаточно медленно растёт, к примеру, log10(10 5 ) == 5 Поэтому не измеряя производительность, сложно сказать какой код (на основе set или sorted) быстрее на заданных входных списках, платформе.
Если дополнительно порядок элементов в B списке не определён ( sorted() не работает) и можно только сравнивать элементы напрямую ( a == b ), то придётся использовать O(n * m) алгоритм аналогичный приведённому в вопросе:
>>> A = [1, "a", 1] >>> B = [[], 1] >>> [item for item in A if item not in B] ['a']
Как set(B) так и sorted(B) не работают в этом случае.
Стоит заметить, что C в примере ( [‘a’] ) не содержит единицу хотя она встречается два раза в A списке и только один раз в B .
Чтобы учесть число повторений в B :
C = [] for item in A: try: B.remove(item) except ValueError: C.append(item) # item not in B
В этом случае C == [‘a’, 1] , а не [‘a’] . Код разрушает B . Алгоритм также O(n * m) .
Для хэшируемых элементов, чтобы учесть количество повторений элементов в B , можно в этом случае collections.Counter использовать как мультимножество:
from collections import Counter A = "abracadabra" B = ['a', 'b', 'c'] Bcount = Counter(B) C = [] for item in A: if Bcount[item] == 0: C.append(item) else: Bcount[item] -= 1
Результат C == [‘r’, ‘a’, ‘a’, ‘d’, ‘a’, ‘b’, ‘r’, ‘a’] отличается от C == [‘r’, ‘d’, ‘r’] полученного выше алгоритмом, который не учитывает количество повторений в B .
Если порядок элементов в результате не важен, то можно упростить код:
C = list((Counter(A) - Counter(B)).elements())
Возможный результат: C == [‘b’, ‘r’, ‘r’, ‘a’, ‘a’, ‘a’, ‘a’, ‘d’] . С точностью до порядка элементов внутри C , он совпадает с предыдущим примером. Оба алгоритма линейные — О(m + n) .
Так как порядок не сохраняется, то имеет смысл использовать просто:
C = Counter(A) - Counter(B) # -> Counter()
так как иначе использование списка для C может создать впечатление, что порядок элементов учитывается.
Если не нужно учитывать ни порядок ни количество повторений, то разницу списков можно найти, используя set (множество — разновидность @Alban ответа):
C = set(A).difference(B) # ->
Видно, что в зависимости от желаемого определения вычитания для списков, разность разные значения принимает:
A = "abracadabra" B = ['a', 'b', 'c'] # C = A - B # -> # нет порядка, нет повторений # -> Counter() # нет порядка # -> ['r', 'd', 'r'] # порядок сохранён, но без учёта повторений в B # -> ['r', 'a', 'a', 'd', 'a', 'b', 'r', 'a'] # порядок + с учётом повторений в B
В разных ситуациях разные определения могут быть полезны. Явной очевидной предпочтительной семантики здесь нет — вероятно поэтому операция вычитания ( A — B ) не определена для списков в Питоне.
