letters = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u",` "v", "w", "x", "y", "z"]
This method of writing the alphabet is very error prone. I would import string and use string.ascii_lowercase in place of letters. If you want to generate your own range of letters for whatever reason, I would write
letters = [chr(n) for n in range(ord('a'), ord('z') + 1)]
since there's then no danger of omitting or duplicating a letter.
password_length = 0 password_numbers = [] password_letters = []
These default values are never used. The defaults for password_numbers and password_letters don't make sense since those variables hold numbers. I would delete all three lines.
if not password_length_input.isnumeric(): print(f"{password_length_input} is not a number, try again:") continue else: password_length = int(password_length_input) print(f"Password length: {password_length}")
I would instead write
try:
password_length = int(password_length_input)
except ValueError:
print(f"{password_length_input} is not a number, try again:")
continue
print(f"Password length: {password_length}")
while True: if password_numbers == password_length: ... break else: ... break
There is no sense in having a while loop here since you always break out of it on the first iteration.
range(0,password_numbers)
You can just write range(password_numbers).
password.append(random.randrange(0,9))
This will append a digit from 0 to 8 inclusive, never 9. If you want all ten digits you should write random.randrange(10). Or, perhaps better, use random.choice(string.digits).
password_string = ''.join([str(item) for item in password])
If you use string.digits then every element of password will be a character so you can simplify this to password_string = ''.join(password).