Checking if a number is a palindrome and is incrementing
If we look at your four different functions, you should be able to see that two are simple and easy to read, this goes in line with Pythons ideas, "simple is better than complex" - zen of Python. This is good as it means that others can read and understand your code with ease. This is a benift to both you and others. It also means if you need to change the functionality slightly, it's simple and easy. With your optimised function they take time to read and understand. This is a trade off, either you have fast code that is hard to understand, or slow but easy to understand code. And so from a human point of view, we prefer slower code. 

I guess you, like I, prefer fast code. This leads to problems. Say we are tasked to make a program, from day 1 we'll be using hard to read code to make something simple. This at first is ok, but then it effects the overall structure of the project. And slowly we've made a monster, a hard to read monster. This is why premature optimisations are bad. 

Instead if you don't worry about speed from the beginning, then you don't fall into this problem. And when you need to increase the performance of your code you can then swap out the old slow code for new fast code, only when it's needed. Sure you have to write a function twice, but at least we don't need to write the entire program again. 

There is also another benefit to using simple code. When you're implementing the optimisation you have a base function to time against. This is good as then you can easily tell if your code is an optimisation, or just added complexity. Your function for example show this, if you time them both against their 'simple' version, you'll find, you haven't optimised the code, you've only obfuscated the code.