Programming is an iterative process. If no one commits the first iteration then no work gets done. Writing bad code is still a lot better than writing no code at all.
For my work at Potato I'm often confronted with first-iteration work. The project I'm working on is quite large, and everything was written in a hurry. Because I have a history with the project I tend to be more forgiving towards my predecessors, as I know what kind of time constraints the project was on when it was made. As the project progresses, little bits of code gets written and re-written, and most of our core code is in its third or fourth generation by now.
Another luxury we can now afford at Potato is to do more internal iterations before considering a ticket to be completed. We can tune the code to be cleaner, to work better with other code and to be more maintainable in the future, all in the very first iteration. But that doesn't change the fact that another developer will look at it and find something else to improve.
One of the biggest challenges for me while working on our startup, Flawless.QA, is to limit my own number of iterations and just push stuff when it works, not when it's up to my personal level of standards. This is scary stuff, especially when you're in the process of opening up your codebase for others to work on, which is what's happening right now at FQA. But it's a good lesson.
There's a right number of iterations for each situation: startups don't need as many iterations as do big projects, especially in the beginning. Just remember that, no matter what code you are facing, your predecessor probably had a reason to build it exactly the way it is, or at the very least had reasons to not spend time on it any longer. Don't underestimate that. Just pick it up from there, and push the next iteration.