In the C implementation inside the Python interpreter, dictionaries are implemented as hash tables. Due to hash collisions, it's possible for two keys to map to the same entry in the hash table, so each item must have its corresponding key and value (or, rather, pointers to these) stored in the hash table right there next to each other, so that the key can be compared to verify that the correct item has been found. Iterating over the items is thus just as straightforward as iterating over the keys or values alone. It's just a matter of which pieces are being returned. (This also explains why iterating over keys and values separately returns them in the same order; exactly the same data structure is being iterated over in both cases.)
The specifics apply only to the standard Python interpreter, CPython, but most hash table implementations operate similarly.