Простой ответ заключается в том, что когда вы выполняете
l1 = ['a','b']
l2 = ['c','d']
for x in l1:
for y in l2:
(a,b)=(x,y)
, я предполагаю, что вы вызываете функцию печати за пределами for l oop (вы не показали, где вы вызывали ее в вставленном коде) . В вашем коде значения a и b переназначаются во время каждой итерации, поэтому, когда вы вызываете его после for l oop, он просто печатает то, чему a и b были присвоены последним.
И когда вы это сделали:
l1 = ['a','b']
l2 = ['c','d']
for (a, b) in product(l1, l2):
print(a, b)
Вы вызвали функцию печати внутри for l oop. Это означает, что он достигается на каждой итерации, поэтому имеет смысл печатать значения a и b на каждой итерации.