Поставь print(i, a) в каждой итерации, и поймёшь динамику развития болезни, хе-хе.
Вообще, модифицировать коллекцию, по которой (или по индексам которой) идёт цикл for, - плохая идея. Последствия, в зависимости от языка, могут быть самыми непредсказуемыми.
Для решения есть несколько типовых подходов:
1) Не трогать исходную коллекцию, а результат собирать в копию, сразу фильтруя элементы:
a = (int(s) for s in input().split())
b = {int(s) for s in input().split()}
c = (n for n in a if n not in b)
print(*c)
(обращаем внимание, что тут 'a' - итератор, а не коллекция, т.к. пробежать надо всего один раз, и для этого хранить список не нужно; а 'b' - множество, т.к. в нём порядок неважен, а скорость поиска важна; 'c' - тоже итератор и по тем же соображениям)
2) Скопировать коллекцию и итерироваться по одному экземпляру, а удалять из другого:
a = [int(s) for s in input().split()]
b = {int(s) for s in input().split()}
c = a.copy()
for i in a:
if i in b:
c.remove(i)
print(*c)
Тут мы бежим по исходному списку, а удаляем из копии. Это менее эффективный вариант, чем предыдущий, т.к. много лишних движений (добавили, потом удалять), да и удаление из середины списка - неэффективная операция. Кстати, удаление по значению из списка тоже неэффективно, т.к. придётся пробежать в среднем половину элементов, чтобы найти нужный. И сам список мы храним, получается, дважды.
3) Итерироваться по индексам и с конца: удаление не затронет элементы с меньшими индексами:
a = [int(s) for s in input().split()]
b = {int(s) for s in input().split()}
for i in range(len(a) - 1, -1, -1):
if a[i] in b:
a.pop(i)
print(*a)
Плюс, по сравнению с предыдущим вариантом, получается в том, что не надо копировать список. А остальные недостатки остаются.
4) Крутить счётчик цикла вручную. Если элемент удаляется, то индексы следующих сместятся к началу, поэтому инкремент не нужен, а если не удаляется, то делаем +1. Этот вариант чатгптшный бот выше приводил. Здесь эффективность - такая же, как и в варианте (3).
В реальных программах, где важна производительность, обычно применяется вариант (1): он обеспечивает однократный пробег по списку, и у него линейная сложность. У остальных алгоритмов, включая твой, сложность - квадратичная (внутри пробега по элементам - ещё один пробег для удаления).