for i in xrange(1, 10000000000000): print i
and this doesn't: for i in range(1, 10000000000000): print i
To make the range() example run, you have to use generative behavior anyway, in some form or another. Generators are a simple way of expressing that kind of algorithmic behavior.(for the record, this little example is being ran on a machine with 2GB of ram)
I know that is a very silly use case for generators, particularly when range() is going to become xrange() anyways - but it is a perfect example of why generative behavior can make things simpler. The trade off is memory vs computation - range() builds the whole list then iterates over it; xrange() generates the next item in the list; use normal list construction when the list is knowably going to be small, use generative behavior when the list is going to be big!
Decorators make the language less simple????? A decorator gives you the ability to modify a function/class at runtime. Decorators have made my python code (where they are useful) much much simpler!! Decorators have given me another dimension to follow DRY with!! Decorators do make the implementation more complex but they make the code you write simpler - the trade off is very clear and the cons are almost non-existent.
If you think decorators are cool, try picking up Common Lisp or Scheme - Macros will rock your socks off.