Python Programming: an Introduction to Computer Science by John Zelle, Franklin, Beedle and Associates, 2004.
This is different from other introductions to Python in that it is an introduction to computer science using the Python language as a most appropriate language to illustrate the principles covered. I feel the book hits its mark square-on.
Guido van Rossum originally intended that one of Python's purposes was to be an excellent educational language and he writes a forward to this book praising it for using Python in this way, and doing it well.
It's one thing to learn how to program but it sure is nice to also learn in an organized way that makes sure one gets the basic concepts and principles, and not just the buzz words and a seat of the pants capability.
This book defines the key concepts and makes sure the reader gets examples and exercises that illustrates these principles in action. The examples and exercises are one of the book's strong points and I especially liked the way they aided one to learn by doing without overwhelming one with tedious details that are extraneous to the main purposes of the exercises.
Intended to be used as a college textbook, the book is perfect for that role. It is written in clear, concise and entertaining prose that is highly readable and keeps the reader moving along at a good clip.
The coverage of object orientation is exceptionally good. Key concepts are really thoroughly covered and this helps to give a solid background of real understanding rather than just a passing familiarity with such terms as encapsulation, inheritance, operator overloading and polymorphism.
The best part of the book, in my opinion, is the chapter on Algorithm Design and Recursion. There are clear explanations of the concepts involved in analyzing the degree of difficulty of solving various problems of size n, and the difference between intractable problems and insoluble problems, a good explanation of the halting problem, and a comparison of various categories of algorithms and their relative efficiencies.
This chapter also covers searching and sorting algorithms in some depth, including linear and binary search techniques, and how to use merge sort. A good comparison of iteration and recursion is most effective, and the Towers of Hanoi problem is nicely analyzed. One learns the significance of linear time algorithms, log time algorithms, and exponential time algorithms.
I recommend this book most highly.