not sure which engine or language your using, but I've got an idea to a few of your issues.
But it only works in such a way that you have to repeatedly tap the movement key to make it work not able to hold it down.
This means your reasponding to a key pressed event, and not a key down event. Key pressed typically means that the key was pressed down and then released. I.e. happens only once per tap. What you need to react to is the KeyDown event, (if an event is what your game uses, and not a state that you have to request on update.) which should happen everyupdate if the key is down.
IndexError: Index is out of key range.
for the [pygame.K_WHATEVERS] in the if statements.
@warnexus is correct on what the error is defined as, but it appears that your specific issue is that you probably have more than one Key Enumerator to work with. I'm guessing that key_states might be Key Up, Key Down, +Shift, +Control, I.e. it is identifying the state of the key that is pressed. I noticed the other parameter, which is "key_pressed", and that is probably the enumerator for a single key being pressed. I.e. key_pressed refers to the specific key, and key_state specifically refers to control or shift button information.