The CPython Bytecode Compiler Is Dumb
Well, yes. It's a naive interpreter. The source is translated to the obvious bytecode. At run time, everything is a CObject, including integers and floats.  Everything which you'd expect to be a dict really is a dict. So you spend a lot of run time checking the types of objects, dispatching, and looking up variables. There's a bit of memoization, I think, to cut down some of the lookups.<p>It's tough to optimize a language where any thread can change the internal variables of any other thread at any time.  Python has gratuitous dynamism. Rarely does code muck with the state of another thread, but it can, and the code has to handle the worst case. There's no such thing as a thread-local variable in Python.