Question: I ask this question because when a loop is debugged with repeated print statements, it slows down the program much more that I would have originally expected. I have gotten used to this, but now I am curious as to the technical reasons why this would be the case? It seems to me that the various calculations and assignings of variables would be more expensive than outputting strings.

Answer: 
Quite a few, but another important (or even the most important) bottleneck is unrelated to the CPU: I/O overhead. Once the bytecode instruction(s) have been dispatched and all arguments have been converted to strings, a function is called to write those strings to `sys.stdout`. Depending on your system and how you run the program, this may be:

1. A file on disk
2. A pipe from a terminal emulator
3. Some Python objects that capture the output (this is what IDLE does IIRC) to do who-knows-what with it (capture it, put it into a GUI, etc).

In case #1, disk I/O is involved and that's easily an order of magnitude slower than writing to RAM. And RAM is already awfully slow compared to today's CPUs. As noted in a comment, this is less of an issue due to extensive buffering by the OS and by Python, but still takes time to issue the write and (depending on implementation details I don't know much about) it may still take some time if someone flushes any buffers prematurely.

In case #2, everything remains in memory, but it's still a system call, some copying, and the other end has to read it and do something with it for you to notice (e.g. render it in a fancy terminal emulator with an anti-aliased font, which is a complex task itself). Less of an issue as it can happen concurrently, but it nevertheless places load on the CPU.

In case #3, all bets are off. It may hash the output with bcrypt and send it to the moon for all we know. Do you happen to use IDLE? I recall a complaint that IDLE was (is?) *very* slow with redirecting output, especially with lots of tine pieces. It has to capture the output, concatenate it with the output so far, and let Tkinter render that.
This is not a matter of CPU instructions, at least not the CPU instructions in your Python program. When you do a `print` with a terminal emulator (command window) as output, the string to be printed is copied into a kernel buffer, then to the terminal process's memory. The overhead is in the context switching (both processes doing system calls, i.e. jumping into kernel mode) and the copying of the string in memory.