E,F,A,B даёт кортеж (5,6,1,2), который к оригинальным переменным уже не имеет никакого отношения и никак с ними не связан.
foo = E,F,A,B
print(foo) # => (5, 6, 1, 2)
E = -777
print(foo) # всё ещё => (5, 6, 1, 2)
Синтаксис A,B,C,D = — это распаковка (в данном случае кортежа) — последовательно присваивает переменным значения из списка, кортежа или любого другого итерируемого объекта (можно поставить = range(4), например), стоящего после знака равно. А тот кортеж, который стоит справа, уже не имеет к оригинальным переменным никакого отношения. То есть получается что-то вроде:
A,B,C,D = (5,6,1,2)
Во втором случае код просто выполняется последовательно как есть и меняет переменные, надеюсь он в пояснениях не нуждается)
Ещё примеров:
a, b, c = [1, 2, 3] # a = 1, b = 2, c = 3
a, b, c = range(3) # a = 0, b = 1, c = 2
a, b, *l, c = range(5) # a = 0, b = 1, l = [2, 3], c = 4
Пример со своим генератором:
def gen():
yield int(input('Первое число: '))
yield int(input('Второе число: '))
a, b = gen()
print(a, b)
Даст:
Первое число: 3
Второе число: 4
3 4