Password generator in python
The other answers have great hints that you should definitely follow.

However, since we are talking about passwords here, a little bit of extra security might not hurt. Especially if it's readily available in the secrets module in Python 3. secrets uses a cryptograhically strong random number generator (in contrast to the pseudo random number generator in the normal random module). There is a special warning in that regard in the docs of random. If you want to stick to random, at least use an instance of random.SystemRandom(), which is basically what secrets does. An example:

RNG = random.SystemRandom()

def password_generator(...):
    ...
    # The remaining values to fill
    type_ = list(types.keys())
    for rem in range(length - num_chars):
        char_list.append(RNG.choice(type_))
        # alternatively
        char_list.append(secrets.choice(type_))
    ...


random.choice uses what is called a pseudo-random number generator, i.e. an algorithm that generates a deterministic "randomly looking" sequence of bytes starting from a given seed. secrets.choice uses a randomness source implemented in the OS, which likely takes electrical noise and other things into consideration to generate non-deterministic random data. random.org has a comprehensive article on the differences at https://www.random.org/randomness/. And of course, there is also the obligatory Wikipedia page about Randomness.