Дополнительные круглые скобки в вопросе вводят другое выражение генератора, которое дает 2 генератора, каждый из которых дает 2 кортежа.Понимание списка ниже точно показывает, что происходит.
>>> [w for w in (((x+y,0) for x in 'cd') for y in 'ab')]
[<generator object <genexpr> at 0x1ca5d70>, <generator object <genexpr> at 0x1ca5b90>]
Понимание списка вместо выражения генератора показывает, что содержат генераторы выше
>>> [w for w in ([(x+y,0) for x in 'cd'] for y in 'ab')]
[[('ca', 0), ('da', 0)], [('cb', 0), ('db', 0)]]
И именно поэтому вы получили дваключ-значение пар кортежей.
Почему работает ответ Муада
>>> [w for w in ((x+y,0) for x in 'cd' for y in 'ab')]
[('ca', 0), ('cb', 0), ('da', 0), ('db', 0)]
В Python 2.7 и 3.0 и выше, вы можете использовать dict-понимания
>>> j = {x+y:0 for x in 'cd' for y in 'ab'}
>>> j
{'cb': 0, 'ca': 0, 'db': 0, 'da': 0}